0

link to issue

I have still a question. Is it possible, to have for each system I reverse proxy like above, to have a separate conf file in the modules-enabled folder. I tried this but, nginx keeps saying, that the stream directive is duplicate. Maybe I can point the one stream module to various server confs, but I don't know how to do that.

Could anyone help?

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
Haydar
  • 61
  • 1
  • 1
  • 8

1 Answers1

0

I played a bit with your use case in my lab environment and you actually found a pretty neat solution to stream proxy pass depending on an incoming subdomain. The main problem is still as mentioned in my comment: you must not have two times the same port you are listening to (in your case 443). That is something you don't have in the big combined file, but you are introducing it in the divided files and as nginx is simply concatenating the separated files the error you mention occurs.

From my point of view by changing the splitting of the files it should work. Here an example I find useful. It consists of 3 parts:

  • a "prefix" part which contains the mapping
  • the servers, add as much as you like. One server has a separate server {} directive with port 5480 as this one is only used once it can go in the server specific file. If that would occur also for other servers, it must go in the suffix file.
  • a "suffix" part which contains the actual proxy pass directive which is always the same due to the usage of the $upstreamvariable

I started the filenames with numbers to ensure their order when nginx concatenates them.

Please note that I have tested this with DNS & servers I have and can control. I did rewrite the examples so that they match your situations. I hope it's working as is, but as I don't have your setup it might not work right away.

Prefix: 00_prefix.conf

map $ssl_preread_server_name:$server_port $upstream {
  tempserver01.domain.com:5480 tempserver01_vapp_5480;
  tempserver01.domain.com:443 tempserver01_backend_443;
  tempserver02.domain.com:443 tempserver02_backend_443;
}

Server 1: 01_realserver01.conf

upstream $upstream {
  hash $remote_addr consistent;
  server duckduckgo.com:443;
}

server {
  listen 5480;
  proxy_pass $upstream;
  ssl_preread on;
}

Server 2: 02_realserver02.conf

upstream $upstream {
  hash $remote_addr consistent;
  server duckduckgo.com:443;
}

You for sure have realized that the server {} part was missing. That’s due to the fact that it is 100% the same in all cases and thus must be separated in one file to ensure that it ends up only 1 time in the concatenated big config nginx is creating out of all the bits and pieces in the separated config files.

Suffix: 99_suffix.conf

server {
  listen 443;
  proxy_pass $upstream;
  ssl_preread on;
}

After having reloaded nginx with nginx -s reload you can check the complete concatinated config nginx has loaded with nginx -T and you'll see something like this:

# configuration file /etc/nginx/stream/enabled/00_prefix.conf:
map $ssl_preread_server_name:$server_port $upstream {
  tempserver01.domain.com:5480 tempserver01_vapp_5480;
  tempserver01.domain.com:443 tempserver01_backend_443;
  tempserver02.domain.com:443 tempserver02_backend_443;
}
# configuration file /etc/nginx/stream/enabled/01_realserver01.conf:
upstream $upstream {
  hash $remote_addr consistent;
  server duckduckgo.com:443;
}

server {
  listen 5480;
  proxy_pass $upstream;
  ssl_preread on;
}
# configuration file /etc/nginx/stream/enabled/02_realserver02.conf:
upstream $upstream {
  hash $remote_addr consistent;
  server duckduckgo.com:443;
}
# configuration file /etc/nginx/stream/enabled/99_suffix.conf:
server {
  listen 443;
  proxy_pass $upstream;
  ssl_preread on;
}

As you can see the separated files are combined in the right order and everything should work as expected. I hope that helps you.

J J
  • 398
  • 1
  • 2
  • 13
  • Hello, this didn't work I have a stream directive which passes the request to the upstream servers. So when I move my file with the stream directive to conf.d, the nginx won't fire up. so I removed the stream directive form the conf file and placed as an include difrective into the nginx.conf where to find the confs, this didn't work either. My main goal is to have for each host a separate stream file. Thanks – Haydar Jan 16 '20 at 15:35
  • Okay, what I understood from your last comment is that you require a specific order which can not be guaranteed by the `include *.conf` command. What you could also do is to use `*.include` files and put them manually in the right order one after another. I have examples of this also in the github repo I mentioned. But I have to be honest: I did not yet fully understand your use case. Can you post an example config file you have today? Maybe it will be clearer then . Thank you. – J J Jan 16 '20 at 20:40
  • Hello, please look above in the answers section. Further I would like to share this config as an tutorial. how can I do this? Thanks Haydar – Haydar Jan 17 '20 at 09:04
  • Ohh, I'm so sorry for the late response. I did not see your explanations. I'll try this in my testlab. So the main goal ist to add as much as possible 0X_realserver0X.conf's and expand the Prefix: 00_prefix.conf for the amount of Servers I want. In total everytime I add a server in the prefix.conf, I need to add a server.conf? Right? – Haydar Feb 25 '20 at 11:52
  • BTW: How do I get the following comment shown on the nginx -T output? # configuration file /etc/nginx/stream/enabled/01_realserver01.conf: – Haydar Feb 25 '20 at 12:12
  • Ahh one m ore thing. It is strange to me, why nginx is listening on port 80? There is no Port 80 configured in the nginx.conf. The only configuration for port 80 ist here /etc/nginx/sites-available/default. This default file is not even in sites-enabled. how come? – Haydar Feb 25 '20 at 14:35
  • **Answer 1)** to [this question](https://stackoverflow.com/questions/59770451/nginx-reverse-proxy-multiple-host-configuration-files-instead-of-one-big-file/59771024?noredirect=1#comment106836521_59771024): yes. **Answer 2)** to [this question](https://stackoverflow.com/questions/59770451/nginx-reverse-proxy-multiple-host-configuration-files-instead-of-one-big-file/59771024?noredirect=1#comment106837173_59771024): `nginx -T` shows all config files it has loaded, each one starting with a comment with the actual folder and filename. If this line is missing, then the config file is also not there. – J J Feb 26 '20 at 12:30
  • **Answer 3 part 1)** to [this question](https://stackoverflow.com/questions/59770451/nginx-reverse-proxy-multiple-host-configuration-files-instead-of-one-big-file/59771024?noredirect=1#comment106842178_59771024): in my case nginx always listens on port 80 as lets encrypt needs that and I alwys optain my certs from there. I have that configured in `/etc/nginx/sites-available/default.conf` which gets loaded just like the rest of `*.config` files in taht folder. – J J Feb 26 '20 at 12:34
  • **Answer 3 part 2)** to [this question](https://stackoverflow.com/questions/59770451/nginx-reverse-proxy-multiple-host-configuration-files-instead-of-one-big-file/59771024?noredirect=1#comment106842178_59771024): When I take a look at your code snippets [here](https://stackoverflow.com/questions/59624481/reverse-proxy-with-nginx-ssl-passthrough) you also listen on port 80 and redirect all traffic to 443, or am I wrong? – J J Feb 26 '20 at 12:34
  • This snippet does not exist anymore. I have now the following situation on my sites-enabled: I have 4 backend Webservers. A call on Port 80 to an external domain should just forward to the backend. The rewrite is done on the backend. so I have 4 backend configurations. All should forward to different backend, which works. BUT if I remove three conf's from the sites-enabled, servers still forwarded correctly to the respective backend. Even if on one " .conf" file only one backend is configured. This is strange to me. How is this possible? [link](https://stackoverflow.com/a/60414543/12666641) – Haydar Feb 26 '20 at 13:15
  • Sorry, I don't get the point of your question. You are asking why nginx is listening on port 80 and in the last comment you say you configured it to listen on port 80. I'm confused :-) ... is there anything else still not working with the seperated config files? – J J Feb 26 '20 at 14:18
  • 1
    Ok, I was sure, that you're going to be confused;-) I'll start a new topic. The separated file thing just works fine. – Haydar Feb 26 '20 at 14:26
  • I had to change the $upstream directive to the mapped name inn here: upstream $upstream { hash $remote_addr consistent; server duckduckgo.com:443; } otherwise it indicated to me that the $upstream is duplicated. so used the mapped name e.g. tempserver01_backend_443. even on 01_realserver01.conf I had to replace it. Any comments? – Haydar Mar 03 '20 at 10:52