{"id":9065,"date":"2022-06-13T22:30:21","date_gmt":"2022-06-14T03:30:21","guid":{"rendered":"https:\/\/www.rushworth.us\/lisa\/?p=9065"},"modified":"2022-06-13T22:30:21","modified_gmt":"2022-06-14T03:30:21","slug":"nginx-auth-proxy","status":"publish","type":"post","link":"https:\/\/www.rushworth.us\/lisa\/?p=9065","title":{"rendered":"NGINX Auth Proxy"},"content":{"rendered":"<p>This example uses Kerberos for SSO authentication using Docker-ized NGINX. To instantiate the sandbox container, I am mapping the conf.d folder into the container and publishing ports 80 and 443<\/p>\n<p><tt>docker run -dit --name authproxy -v \/usr\/nginx\/conf.d:\/etc\/nginx\/conf.d -p 80:80 -p 443:443 -d centos:latest<\/tt><\/p>\n<p>Shell into the container, install Kerberos, and configure it to use your domain (in this example, it is my home domain.<\/p>\n<p><tt>docker exec -it authproxy bash<\/tt><\/p>\n<pre># Fix the repos \u2013 this is a docker thing, evidently \u2026\r\ncd \/etc\/yum.repos.d\/\r\nsed -i 's\/mirrorlist\/#mirrorlist\/g' \/etc\/yum.repos.d\/CentOS-*\r\nsed -i 's|#baseurl=http:\/\/mirror.centos.org|baseurl=http:\/\/vault.centos.org|g' \/etc\/yum.repos.d\/CentOS-*\r\n# And update everything just because\r\ndnf update\r\n# Install required stuff\r\ndnf install vim wget git gcc make pcre-devel zlib-devel krb5-devel<\/pre>\n<p>Install NGINX from source and include the spnego-http-auth-nginx-module module<\/p>\n<pre>wget http:\/\/nginx.org\/download\/nginx-1.21.6.tar.gz\r\ngunzip nginx-1.21.6.tar.gz\r\ntar vxf nginx-1.21.6.tar\r\ncd nginx-1.21.6\/\r\ngit clone https:\/\/github.com\/stnoonan\/spnego-http-auth-nginx-module.git\r\ndnf install gcc make pcre-devel zlib-devel krb5-devel\r\n.\/configure --add-module=spnego-http-auth-nginx-module\r\nmake\r\nmake install<\/pre>\n<p>Configure Kerberos on the server to use your domain:<\/p>\n<pre>root@aadac0aa21d5:\/# cat \/etc\/krb5.conf\r\nincludedir \/etc\/krb5.conf.d\/\r\n[logging]\r\ndefault = FILE:\/var\/log\/krb5libs.log\r\nkdc = FILE:\/var\/log\/krb5kdc.log\r\nadmin_server = FILE:\/var\/log\/kadmind.log\r\n[libdefaults]\r\ndns_lookup_realm = false\r\nticket_lifetime = 24h\r\nrenew_lifetime = 7d\r\nforwardable = true\r\nrdns = false\r\ndefault_realm = EXAMPLE.COM\r\n# allow_weak_crypto = true\r\n# default_tgs_enctypes = arcfour-hmac-md5 des-cbc-crc des-cbc-md5\r\n# default_tkt_enctypes = arcfour-hmac-md5 des-cbc-crc des-cbc-md5\r\ndefault_ccache_name = KEYRING:persistent:%{uid}\r\n[realms]\r\nEXAMPLE.COM= {\r\n   kdc = DC01.EXAMPLE.COM\r\n   admin_server = DC01.EXAMPLE.COM\r\n}<\/pre>\n<p>Create a service account in AD &amp; obtain a keytab file:<\/p>\n<p><tt>ktpass \/out nginx.keytab \/princ HTTP\/docker.example.com@example.com -SetUPN \/mapuser nginx \/crypto AES256-SHA1 \/ptype KRB5_NT_PRINCIPAL \/pass Th2s1sth3Pa=s -SetPass \/target dc01.example.com<\/tt><\/p>\n<p>Transfer the keytab file to the NGINX server. Add the following to the server{} section or location{} section to require authentication:<\/p>\n<pre>auth_gss on;\r\nauth_gss_keytab \/path\/to\/nginx\/conf\/nginx.keytab;\r\nauth_gss_delegate_credentials on;<\/pre>\n<p>You will also need to insert header information into the nginx config:<\/p>\n<pre>proxy_pass http:\/\/www.example.com\/authtest\/;\r\nproxy_set_header Host \"www.example.com\"; # I need this to match the host header on my server, usually can use data from $host\r\nproxy_set_header X-Original-URI $request_uri; # Forward along request URI\r\nproxy_set_header X-Real-IP $remote_addr; # pass on real client's IP\r\nproxy_set_header X-Forwarded-For \"LJRAuthPrxyTest\";\r\nproxy_set_header X-Forwarded-Proto $scheme;\r\nproxy_set_header Authorization $http_authorization;\r\nproxy_pass_header Authorization;\r\nproxy_set_header X-WEBAUTH-USER $remote_user;\r\nproxy_read_timeout 900;<\/pre>\n<p>Run NGINX: <tt>\/usr\/local\/nginx\/sbin\/nginx<\/tt><\/p>\n<p>In and of itself, this is the equivalent of requiring authentication \u2013 any user \u2013 to access a site. The trick with an auth proxy is that the server must trust the header data you inserted \u2013 in this case, I have custom PHP code that looks for X-ForwardedFor to be \u201cLJRAuthPrxyTest\u201d and, if it sees that string, reads X-WEBAUTH-USER for the user\u2019s logon name.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"869\" height=\"247\" class=\"wp-image-9066\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-3.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-3.png 869w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-3-300x85.png 300w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-3-768x218.png 768w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-3-750x213.png 750w\" sizes=\"auto, (max-width: 869px) 100vw, 869px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"668\" height=\"155\" class=\"wp-image-9067\" src=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-4.png\" srcset=\"https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-4.png 668w, https:\/\/www.rushworth.us\/lisa\/wp-content\/uploads\/2022\/06\/word-image-4-300x70.png 300w\" sizes=\"auto, (max-width: 668px) 100vw, 668px\" \/><\/p>\n<p>In my example, the Apache site is configured to only accept connections from my NGINX instance:<\/p>\n<pre>&lt;RequireAll&gt;\r\n     Require ip 10.1.3.5\r\n&lt;\/RequireAll&gt;<\/pre>\n<p>This prevents someone from playing around with header insertion and spoofing authentication.<\/p>\n<p>Some applications allow auth proxying, and the server documentation will provide guidance on what header values need to be used.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This example uses Kerberos for SSO authentication using Docker-ized NGINX. To instantiate the sandbox container, I am mapping the conf.d folder into the container and publishing ports 80 and 443 docker run -dit &#8211;name authproxy -v \/usr\/nginx\/conf.d:\/etc\/nginx\/conf.d -p 80:80 -p 443:443 -d centos:latest Shell into the container, install Kerberos, and configure it to use your &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30],"tags":[295,1658,328,375,1659],"class_list":["post-9065","post","type-post","status-publish","format-standard","hentry","category-system-administration","tag-authentication","tag-authorization","tag-kerberos","tag-single-sign-on","tag-spnego"],"_links":{"self":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/9065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9065"}],"version-history":[{"count":1,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/9065\/revisions"}],"predecessor-version":[{"id":9068,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/9065\/revisions\/9068"}],"wp:attachment":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=9065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=9065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}