Create a simple HTTPS server with OPENSSL S_SERVER

This post will mostly serve as a reference for future posts, the goal is to create the simplest HTTPS webserver possible, which will serve to test certificates, authentication via private keys and in the end; configure SSL offloading to an Apache HTTPD, which will act as a proxy between your client and the secure endpoint.
GOAL: At the end of this article, you will have a running secure web server which you can access via your web browser and/or via an SSL client.


First we need to do a bit of preparation, we need to create two certificates which will be used by the OpenSSL s_server command.

Note; You’ll only need to run this command once

joris@beanie ~
$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes

Fill in the details of your brand new certificate.
(Explanation of the arguments can be found at the bottom of this post)

Starting the OpenSSL s_server

joris@beanie ~
$ openssl s_server -key key.pem -cert cert.pem -accept 44330 -www
Using default temp DH parameters

(Explanation of the arguments can be found at the bottom of this post)
Right now, we’ve got a running secure server on port 44330

Accessing the s_server via web browser

We can test our openssl s_server by accessing the following URL via your web browser:
If everything went right, you’ll see a privacy error, this is because we’re using a self-signed certificate (created in the preparation)
2015-07-22 11_38_00-Privacy error
After you continued past the privacy error, you’ll see the response from the openssl s_server internal webserver:
2015-07-22 11_38_38-https___localhost_44330

Accessing the s_server via openssl s_client

To create a full circle, we’ll make sure our s_server is actually working by accessing it via openssl s_client:
joris@beanie ~
$ openssl s_client -connect localhost:44330
depth=0 C = NL, ST = Utrecht, L = Utrecht, O = Company, OU = Unit, CN = localhos t
verify error:num=18:self signed certificate
verify return:1
depth=0 C = NL, ST = Utrecht, L = Utrecht, O = Company, OU = Unit, CN = localhos t
verify return:1
Certificate chain
0 s:/C=NL/ST=Utrecht/L=Utrecht/O=Company/OU=Unit/CN=localhost
Server certificate
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
SSL handshake has read 1598 bytes and written 481 bytes
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
No ALPN negotiated
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 650699D3308814F24A6F509AD74978103D7CB9D9C5E03F0EAEEC46B9D58ECA8B
Master-Key: 84421FF2D9EF1855C050367A304D37030D11D9C6071C9F5FB2B7FECFE38FCC8B 4C9D5FE42C1BF530FD79CFA41A416B40
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 46 f4 7a 4f bb 9c 77 a7-dc 8e 2a 0e d8 0a f0 a9 F.zO..w...*.....
0010 - 72 85 d1 64 9a 1d 25 7d-20 fc ab 58 fc e3 d4 05 r..d..%} ..X....
0020 - 95 dc b0 77 75 35 00 08-e8 2b 26 a2 24 28 18 0c ...wu5...+&.$(..
0030 - 6d 1d e4 8a 52 bb ce 15-04 c6 5a e2 2b f1 64 3d m...R.....Z.+.d=
0040 - 0d cf 31 6e 1d 6e 5e 7c-31 42 24 81 b8 87 b8 d0 ..1n.n^|1B$.....
0050 - 30 46 e4 9a 60 ca e6 99-9b 64 a2 4f 81 8f 66 40 0F..`....d.O..f@
0060 - 7e d2 7d 86 70 32 5c 6d-25 dd f8 00 21 6b b4 eb ~.}.p2\m%...!k..
0070 - 3f 03 32 a3 b6 cc bd a8-31 25 5b 96 1d aa ab a6 ?.2.....1%[.....
0080 - ef 15 f5 4f bd 82 e1 b7-7b cb 47 5b 39 56 94 84 ...O....{.G[9V..
0090 - e0 e3 df 4f 76 3d 8c d1-f0 43 75 88 db fe 91 6e ...Ov=...Cu....n

Compression: 1 (zlib compression)
Start Time: 1437553463
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)

joris@beanie ~

Explanation of the openssl req command

openssl (OpenSSL command)
PKCS#10 certificate request and certificate generating utility.

this option outputs a self signed certificate instead of a certificate request. This is typically used to generate a test certificate or a self signed root CA. The extensions added to the certificate (if any) are specified in the configuration file. Unless specified using the set_serial option, a large random number will be used for the serial number.

-newkey rsa:2048
this option creates a new certificate request and a new private key. The argument takes one of several forms. rsa:nbits, where nbits is the number of bits, generates an RSA key nbits in size. If nbits is omitted, i.e. -newkey rsa specified, the default key size, specified in the configuration file is used.

-keyout key.pem
this gives the filename to write the newly created private key to. If this option is not specified then the filename present in the configuration file is used.

-out cert.pem
This specifies the output filename to write to or standard output by default.

-days 365
when the -x509 option is being used this specifies the number of days to certify the certificate for. The default is 30 days.

if this option is specified then if a private key is created it will not be encrypted.

Explanation of the openssl s_server command


The s_server command implements a generic SSL/TLS server which listens for connections on a given port using SSL/TLS.

-key key.pem

The private key to use. If not specified then the certificate file will be used.

-cert cert.pem

The certificate to use, most servers cipher suites require the use of a certificate and some require a certificate with a certain public key type: for example the DSS cipher suites require a certificate containing a DSS (DSA) key. If not specified then the filename "server.pem" will be used.

-accept 44330

the TCP port to listen on for connections. If not specified 4433 is used.


sends a status message back to the client when it connects. This includes lots of information about the ciphers used and various session parameters. The output is in HTML format so this option will normally be used with a web browser.



6 Replies to “Create a simple HTTPS server with OPENSSL S_SERVER”

  1. Great little introduction! And it works! I built and installed the latest OpenSSL from source so that I could step through the source in GDB. The tutorial allowed me to get started immediately with no fuss. Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.