I’d like to know how to configure nginx to get 2 domains working on one server (1 ip address).
I want to setup a Keycloak SSO next to a bookstack instance.
My issue is that when I want to access bookstack.domain.com it redirects to keycloak.domain.com.
Here’s my /etc/nginx/conf.d/keycloak.conf :
upstream keycloak {
# Use IP Hash for session persistence
ip_hash;
# List of Keycloak servers
server 127.0.0.1:8080;
}
server {
listen 80;
server_name keycloak.domain.com;
# Redirect all HTTP to HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name keycloak.domain.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/certificate_key.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://keycloak;
}
}
Here’s my /etc/nginx/conf.d/bookstack.conf :
server {
listen 3480;
access_log /var/log/nginx/bookstack_access.log;
error_log /var/log/nginx/bookstack_error.log;
server_name bookstack.domain.com;
root /var/www/bookstack/public;
#
# redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
#
return 301 https://$host$request_uri;
}
server {
listen 5443 ssl http2;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/certificate_key.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AE;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem;
server_name bookstack.domain.com;
#HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
root /var/www/bookstack/public;
access_log /var/log/nginx/bookstack_access.log;
error_log /var/log/nginx/bookstack_error.log;
client_max_body_size 1G;
fastcgi_buffers 64 4K;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ ^/(?:.htaccess|data|config|db_structure.xml|README) {
deny all;
}
location ~ .php(?:$|/) {
fastcgi_split_path_info ^(.+.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/var/run/php-fpm.sock;
}
location ~* .(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
expires 30d;
access_log off;
}
}
Please let me know 🙂
2
Answers
Your keycloak config seems ok
It listen on port
80 (http)
and port443 (https)
and all requests to80 (http)
are redirected to443 (https)
Your bookstack config looks wrong for me
It does not listen to port
80
or443
(instead it listen to5443
and3480
). If you don’t have some kind of special port forwarding then I think request tobookstack.domain.com
will never reach the nginx-server defined inbookstack.conf
and as a result the only matching server will serve the request => keycloakYou should change
bookstack.conf
‘s Listen ports:This is exactly expected nginx behavior for the given configuration. One of the
server
blocks always act as default server for any request arriving on some IP/port combination no matter what is theHost
HTTP header value. Here is an official documentation on this subject. You can usedefault_server
parameter for thelisten
directive to explicitly specifyserver
block that should act as the default server or it will be the firstserver
block that listen on those IP/port otherwise. On multihomed servers things can be more complicated, as discussed here.Now back to the question. You have four server blocks in your configuration: first one listen on TCP port 80 (default port for
http://
scheme), second one listen on TCP port 443 (default port forhttps://
scheme), one listen on port 3480 and the last one listen on port 5443. Since there is only oneserver
block listening each port, eachserver
block will act as default server for any request coming to that port. So if you typehttp://bookstack.domain.com
in your browser address bar, default port 80 forhttp://
scheme will be used and your request will be redirected tohttps://keycloak.domain.com
. You are usingfor redirection, and the
$server_name
variable will be alwayskeycloak.domain.com
for that server block (read this answer to understand the difference between$host
,$http_host
and$server_name
variables). If you explicitly specify the port and typehttp://bookstack.domain.com:3480
, your request will be served by the thirdserver
block thus being redirected tohttps://bookstack.domain.com
(here your are using$host
variable which is right). Default TCP porthttps://
scheme is 443. But the onlyserver
block that listen on that port is forkeycloak.domain.com
! Oops. The only way you can reach yourbookstack.domain.com
is to typehttps://bookstack.domain.com:5443
in your browser. And if you correctly understand all the above information, you can typehttps://keycloak.domain.com:5443
too, it won’t made any difference.Well, I tried to explain what happened here with your nginx configuration. Get rid of non-standard ports as @Evil_skunk recommends you in his answer. Don’t forget to clear your browser cache before trying new configuration – permanent HTTP 301 redirects are often cached by the browsers, unlike temporary HTTP 302 redirects.