ML
    • Recent
    • Categories
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login

    How to setup Nginx TLS certificate based Authentication (VPN alternative)

    IT Discussion
    nginx tls ssl cert certificate authentication
    4
    21
    6.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Emad RE
      Emad R
      last edited by Emad R

      Hello this will be quick and dirty guide for setting nginx with TLS based authentication. It an idea I researched after seeing @scottalanmiller video comparing this with VPN, I will not include many setting like selinux or firewalld or nginx config in separate files instead of the main config, however feel free to enhance this. I am happy that I got it working thus writing it (This guide uses Centos 7 minimal as a base).

      yum -y install epel-release
      yum -y install nginx
      systemctl start nginx
      systemctl enable nginx
      mkdir /etc/pki/nginx
      mkdir /etc/pki/nginx/private
      chmod 700 /etc/pki/nginx
      chmod 700 /etc/pki/nginx/private
      cd /etc/pki/nginx
      openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/pki/nginx/private/server.key -out /etc/pki/nginx/server.crt
      

      What we did above, is installed nginx + prepared directory that is already mentioned in nginx main config and created 2 self signed certificates for https.
      Dont get this confused with self signed certificates for clients, this is another step we will do right now, stay in /etc/pki/nginx:

      openssl genrsa -des3 -out ca.key 4096
      openssl req -new -x509 -days 365 -key ca.key -out ca.crt
      
      openssl genrsa -des3 -out client.key 4096
      openssl req -new -key client.key -out client.csr
      openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
      openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
      openssl pkcs12 -in client.p12 -out client.pem -clcerts
      

      The first 2 files creates the CA (Certifcate Authority), while the rest 5 commands deals with creation of client cert, and feel free to rename client to the name of user,
      also the last 2 lines exports the client cert to p12 and pem format. I didnt need the pem format FYI.

      nano /etc/nginx/nginx.conf
      
      # Settings for a TLS enabled server.
      server {
          listen       443 ssl http2 default_server;
          listen       [::]:443 ssl http2 default_server;
          server_name  _;
          root         /usr/share/nginx/html;
      
          ssl_certificate "/etc/pki/nginx/server.crt";
          ssl_certificate_key "/etc/pki/nginx/private/server.key";
          ssl_session_cache shared:SSL:1m;
          ssl_session_timeout  10m;
          ssl_ciphers HIGH:!aNULL:!MD5;
          ssl_prefer_server_ciphers on;
      	ssl_client_certificate "/etc/pki/nginx/ca.crt";		
      	ssl_verify_client on;
      
      
      
      We only ammended 4 lines:
      1) Ensure ssl_certificate for https points to the right file
      2) Ensure ssl_certificate_key for https points to the right file
      3) added ssl_client_certificate "/etc/pki/nginx/ca.crt";		
      4) added ssl_verify_client on;
      

      Now I needed to manually add the ca.crt file to "/etc/pki/tls/certs/ca-bundle.crt" (this took days of research)...
      So copy the contents of "/etc/pki/nginx/ca.crt" and paste it at the end of "/etc/pki/tls/certs/ca-bundle.crt" or use this command:

      cat /etc/pki/nginx/ca.crt >> /etc/pki/tls/certs/ca-bundle.crt
      

      Finally restart nginx

      systemctl restart nginx
      

      and copy the p12 file you created in "/etc/pki/nginx/client.p12" to your client machines be it a Windows or Linux or Mac OS X as long as it has good web browser.
      And install it into the webbrowser, I choose the Personal Store and make sure when you click advanced all the ticks are checked for it is usage.

      0_1502526519235_2017-08-12 11_22_54-Settings.png

      0_1502526523823_2017-08-12 11_22_58-Settings.png

      0_1502526541920_2017-08-12 11_23_07-Settings.png

      Now open the IP of your https machines, if you didnt import the P12 file you will see "400 Bad Request No required SSL certificate was sent"

      However if you did you will be able to select the cert and cotinue to login:

      0_1502526510048_2017-08-12 11_27_17-New Tab.png

      This works wonders paired with proxy, which @JaredBusch wrote article about:

      https://mangolassi.it/post/124064

      Special thanks to --> https://gist.github.com/mtigas/952344

      Emad RE JaredBuschJ 3 Replies Last reply Reply Quote 3
      • A
        Alex Sage
        last edited by

        This is very cool!

        Can I revoke a client certificate? Say if the employee leaves the company?

        Emad RE 1 Reply Last reply Reply Quote 0
        • A
          Alex Sage
          last edited by

          What about mobile devices? I assume you can install the certificate there as well?

          Emad RE 1 Reply Last reply Reply Quote 0
          • Emad RE
            Emad R @Alex Sage
            last edited by

            @aaronstuder said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

            What about mobile devices? I assume you can install the certificate there as well?

            https://support.google.com/nexus/answer/2844832?hl=en

            1 Reply Last reply Reply Quote 0
            • Emad RE
              Emad R @Alex Sage
              last edited by

              @aaronstuder said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

              This is very cool!

              Can I revoke a client certificate? Say if the employee leaves the company?

              Good question, going back to another guide I saw had this article:

              https://arcweb.co/securing-websites-nginx-and-client-side-certificate-authentication-linux/

              Revoking Certificates

              On one final note, as with all exercises, it’s important to be practical and know that things change. Inevitably there will come a time when someone leaves your team and their certificate needs to be invalidated. Running the following script with the correct username will add the user’s certificate to the revocation list and ensure that they can no longer access the site:

              openssl ca -name CA_Default  
              -revoke /etc/ssl/ca/certs/users/USERNAME.crt 
              -keyfile /etc/ssl/ca/private/ca.key 
              -cert /etc/ssl/ca/certs/ca.crt
              
              openssl ca -name CA_Default -gencrl 
                  -keyfile /etc/ssl/ca/private/ca.key 
                  -cert /etc/ssl/ca/certs/ca.crt 
                  -out /etc/ssl/ca/private/ca.crl 
                  -crldays 1095
              
              

              I dont know why he posted 2 commands, it seems the first one does the trick.

              JaredBuschJ 1 Reply Last reply Reply Quote 0
              • JaredBuschJ
                JaredBusch @Emad R
                last edited by

                @emad-r because you only link a single cert in the nginx config.

                So once you revoke one user, you need to rebuild the full cert with that user excluded.

                1 Reply Last reply Reply Quote 2
                • Emad RE
                  Emad R @Emad R
                  last edited by

                  @emad-r

                  If you are trying this and testing it out with Chrome without success, please make sure to test and exit chrome completely then open it again and check if the results changed or not.

                  1 Reply Last reply Reply Quote 0
                  • NashBrydgesN
                    NashBrydges
                    last edited by

                    @Emad-R Am I understanding this correctly? Is this to prevent access to a site to anyone who doesn't have the cert installed in their browser? If so, do you think this can be restricted in scope to only a single page or set of pages? For example, a public site with some admin functions via a login page, could this be used to continue to allow public access to the public pages but used to restrict access to the login and admin pages to only those with the cert? I suppose I've have to use Nginx and this config only for those restricted pages and a different config for the public space (if that's even possible).

                    JaredBuschJ Emad RE 2 Replies Last reply Reply Quote 0
                    • JaredBuschJ
                      JaredBusch @NashBrydges
                      last edited by JaredBusch

                      @nashbrydges said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                      @Emad-R Am I understanding this correctly? Is this to prevent access to a site to anyone who doesn't have the cert installed in their browser? If so, do you think this can be restricted in scope to only a single page or set of pages? For example, a public site with some admin functions via a login page, could this be used to continue to allow public access to the public pages but used to restrict access to the login and admin pages to only those with the cert? I suppose I've have to use Nginx and this config only for those restricted pages and a different config for the public space (if that's even possible).

                      Simply use a different URL for the restricted pages versus open pages.
                      secure.domain.com vs www.domain.com

                      Only have the client certs in the nginx config for the secure.domain.com server block.

                      Both blocks can still be SSL.

                      Which i might add, is why he should have put everything in separate config files and not screw up the default nginx.conf

                      NashBrydgesN 1 Reply Last reply Reply Quote 2
                      • NashBrydgesN
                        NashBrydges @JaredBusch
                        last edited by

                        @jaredbusch said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                        @nashbrydges said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                        @Emad-R Am I understanding this correctly? Is this to prevent access to a site to anyone who doesn't have the cert installed in their browser? If so, do you think this can be restricted in scope to only a single page or set of pages? For example, a public site with some admin functions via a login page, could this be used to continue to allow public access to the public pages but used to restrict access to the login and admin pages to only those with the cert? I suppose I've have to use Nginx and this config only for those restricted pages and a different config for the public space (if that's even possible).

                        Simply use a different URL for the restricted pages versus open pages.
                        secure.domain.com vs www.domain.com

                        Only have the client certs in the nginx config for the secure.domain.com server block.

                        Both blocks can still be SSL.

                        Nice! Didn't think of using a sub-domain. Definitely going to have to give this a try.

                        1 Reply Last reply Reply Quote 0
                        • Emad RE
                          Emad R @NashBrydges
                          last edited by Emad R

                          @nashbrydges said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                          @Emad-R Am I understanding this correctly? Is this to prevent access to a site to anyone who doesn't have the cert installed in their browser? If so, do you think this can be restricted in scope to only a single page or set of pages? For example, a public site with some admin functions via a login page, could this be used to continue to allow public access to the public pages but used to restrict access to the login and admin pages to only those with the cert? I suppose I've have to use Nginx and this config only for those restricted pages and a different config for the public space (if that's even possible).

                          Hey Nash,
                          Correct, no one can see the site without installed the p12 file in their browser. Will get error page instead.

                          Well I dont use this to restrict pages persay, more like be front end for whole site, whole HTTP unsecure server. and nginx can be installed on the same machine or another and act as gateway for it.

                          Imagine good knowledge base article for company that resides in the Intranet, local machine in LAN using Apache/MySQL (Think Wordpress) and some people said it is good if they can access it remotely.

                          So my previous options was to use VPN or if the users are another site with static IP (rare and limited) you can create firewall rules, however using this new method I can just install nginx and setup TLS certificate authentication and provide users with p12 file and run nginx on https and make it a front end proxy for that KB site.

                          JaredBuschJ 1 Reply Last reply Reply Quote 1
                          • NashBrydgesN
                            NashBrydges
                            last edited by

                            It's official, I'm NEVER getting through my to-do list. Must stop coming here. Lol

                            1 Reply Last reply Reply Quote 2
                            • JaredBuschJ
                              JaredBusch @Emad R
                              last edited by

                              @emad-r said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                              Now I needed to manually add the ca.crt file to "/etc/pki/tls/certs/ca-bundle.crt" (this took days of research)...
                              So copy the contents of "/etc/pki/nginx/ca.crt" and paste it at the end of "/etc/pki/tls/certs/ca-bundle.crt" Finally restart nginx

                              # Append the ca.crt to the ca-bundle.crt
                              cat /etc/pki/nginx/ca.crt >> /etc/pki/tls/certs/ca-bundle.crt
                              
                              1 Reply Last reply Reply Quote 1
                              • JaredBuschJ
                                JaredBusch @Emad R
                                last edited by JaredBusch

                                @emad-r said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                                @nashbrydges said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                                @Emad-R Am I understanding this correctly? Is this to prevent access to a site to anyone who doesn't have the cert installed in their browser? If so, do you think this can be restricted in scope to only a single page or set of pages? For example, a public site with some admin functions via a login page, could this be used to continue to allow public access to the public pages but used to restrict access to the login and admin pages to only those with the cert? I suppose I've have to use Nginx and this config only for those restricted pages and a different config for the public space (if that's even possible).

                                Hey Nash,
                                Correct, no one can see the site without installed the p12 file in their browser. Will get error page instead.

                                Well I dont use this to restrict pages persay, more like be front end for whole site, whole HTTP unsecure server. and nginx can be installed on the same machine or another and act as gateway for it.

                                Imagine good knowledge base article for company that resides in the Intranet, local machine in LAN using Apache/MySQL (Think Wordpress) and some people said it is good if they can access it remotely.

                                So my previous options was to use VPN or if the users are another site with static IP (rare and limited) you can create firewall rules, however using this new method I can just install nginx and setup TLS certificate authentication and provide users with p12 file and run nginx on https and make it a front end proxy for that KB site.

                                You will also now have to replace client certificates yearly.

                                Emad RE 1 Reply Last reply Reply Quote 1
                                • Emad RE
                                  Emad R @Emad R
                                  last edited by

                                  @emad-r

                                  Unfortunately , while I did learn alot new stuff and ways. The original reason for learning this failed me.

                                  What I did I install Fedora LXDE spin

                                  Then installed ontop of that VNC on port 5901 made it run on local host

                                  Then using No VNC and Websockify (is a WebSocket to TCP proxy/bridge. This allows a browser to connect to any application/server/service. Implementations in Python, C, Node.js and Ruby.) Which creates a neat HTML 5 interface for VNC service, I configured this to listen to 127.0.0.1:5901 and output to port 7777
                                  so http://192.168.1.x:7777
                                  allows me to connect to my machine.

                                  stay with me.

                                  Using this method I tried to proxy http://192.168.1.x:7777 and use nginx extra security

                                  It worked and installed on Fedora, and I can reach the noVNC connection dialog only after inserting the p12 key, however this lame login page:

                                  https://kanaka.github.io/noVNC/img/noVNC-5.png

                                  with the host and port option, does not allow me to finish the connection, I tried many options but I am so confused with all the proxying that I rather drop it, I feel like If I do more effort I might open proxy to another dimension.

                                  NashBrydgesN 1 Reply Last reply Reply Quote 0
                                  • Emad RE
                                    Emad R @JaredBusch
                                    last edited by

                                    @jaredbusch said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                                    @emad-r said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                                    @nashbrydges said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                                    @Emad-R Am I understanding this correctly? Is this to prevent access to a site to anyone who doesn't have the cert installed in their browser? If so, do you think this can be restricted in scope to only a single page or set of pages? For example, a public site with some admin functions via a login page, could this be used to continue to allow public access to the public pages but used to restrict access to the login and admin pages to only those with the cert? I suppose I've have to use Nginx and this config only for those restricted pages and a different config for the public space (if that's even possible).

                                    Hey Nash,
                                    Correct, no one can see the site without installed the p12 file in their browser. Will get error page instead.

                                    Well I dont use this to restrict pages persay, more like be front end for whole site, whole HTTP unsecure server. and nginx can be installed on the same machine or another and act as gateway for it.

                                    Imagine good knowledge base article for company that resides in the Intranet, local machine in LAN using Apache/MySQL (Think Wordpress) and some people said it is good if they can access it remotely.

                                    So my previous options was to use VPN or if the users are another site with static IP (rare and limited) you can create firewall rules, however using this new method I can just install nginx and setup TLS certificate authentication and provide users with p12 file and run nginx on https and make it a front end proxy for that KB site.

                                    You will also now have to replace client certificates yearly.

                                    But that is good security practice as well. I will know when this happens when they all complain the same time about site access 🙂 no need to set reminder

                                    1 Reply Last reply Reply Quote 0
                                    • NashBrydgesN
                                      NashBrydges @Emad R
                                      last edited by

                                      @emad-r said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                                      @emad-r

                                      Unfortunately , while I did learn alot new stuff and ways. The original reason for learning this failed me.

                                      What I did I install Fedora LXDE spin

                                      Then installed ontop of that VNC on port 5901 made it run on local host

                                      Then using No VNC and Websockify (is a WebSocket to TCP proxy/bridge. This allows a browser to connect to any application/server/service. Implementations in Python, C, Node.js and Ruby.) Which creates a neat HTML 5 interface for VNC service, I configured this to listen to 127.0.0.1:5901 and output to port 7777
                                      so http://192.168.1.x:7777
                                      allows me to connect to my machine.

                                      stay with me.

                                      Using this method I tried to proxy http://192.168.1.x:7777 and use nginx extra security

                                      It worked and installed on Fedora, and I can reach the noVNC connection dialog only after inserting the p12 key, however this lame login page:

                                      https://kanaka.github.io/noVNC/img/noVNC-5.png

                                      with the host and port option, does not allow me to finish the connection, I tried many options but I am so confused with all the proxying that I rather drop it, I feel like If I do more effort I might open proxy to another dimension.

                                      I prefer using Guacamole for all my remote access needs but I think I'll definitely implement something like this to restrict access to my own staff.

                                      1 Reply Last reply Reply Quote 4
                                      • A
                                        Alex Sage
                                        last edited by Alex Sage

                                        Couldn't I change the number of days to something longer?

                                        Emad RE 1 Reply Last reply Reply Quote 0
                                        • Emad RE
                                          Emad R @Alex Sage
                                          last edited by

                                          @aaronstuder said in How to setup Nginx TLS certificate based Authentication (VPN alternative):

                                          Couldn't I change the number of days to something longer?

                                          yh ofcourse, replace all the 365 in the above commands to whatever you want.

                                          A 1 Reply Last reply Reply Quote 1
                                          • A
                                            Alex Sage @Emad R
                                            last edited by

                                            @emad-r 3650 🙂

                                            JaredBuschJ 1 Reply Last reply Reply Quote 0
                                            • 1
                                            • 2
                                            • 1 / 2
                                            • First post
                                              Last post