How do i configure minio using iis as a reverse proxy - iis

I am trying to configure minio using IIS as a reverse proxy.
I want the main service to run from minio.mysite.com and the console to run from console.minio.mysite.com, both of which is already configured with my webhost/dns.
docker-compose.yml
version: '3.7'
networks:
minio_network2:
name: minio_network2
services:
minio_web2:
image: quay.io/minio/minio:RELEASE.2021-10-23T03-28-24Z
container_name: minio_web2
restart: unless-stopped
command: server --console-address ":9001" /data
environment:
MINIO_ROOT_USER: multinerd#mysite.com
MINIO_ROOT_PASSWORD: super_secure_pass
# MINIO_SERVER_URL: https://minio.mysite.com
# MINIO_BROWSER_REDIRECT_URL: https://console.minio.mysite.com
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
networks:
- minio_network2
volumes:
- ./minio-data/minio:/data
minio_nginx2:
image: nginx:1.19.2-alpine
container_name: minio_nginx2
restart: unless-stopped
hostname: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "3009:9000" ## Client
- "30091:9001" ## Console
depends_on:
- minio_web2
networks:
- minio_network2
nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 4096;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# include /etc/nginx/conf.d/*.conf;
upstream minio {
server minio_web2:9000;
}
upstream console {
ip_hash;
server minio_web2:9001;
}
server {
listen 9000;
listen [::]:9000;
server_name localhost;
# To allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# To disable buffering
proxy_buffering off;
location / {
proxy_set_header Host $http_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_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://minio;
}
}
server {
listen 9001;
listen [::]:9001;
server_name localhost;
# To allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# To disable buffering
proxy_buffering off;
location / {
proxy_set_header Host $http_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_set_header X-NginX-Proxy true;
# This is necessary to pass the correct IP to be hashed
real_ip_header X-Real-IP;
proxy_connect_timeout 300;
# To support websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
chunked_transfer_encoding off;
proxy_pass http://console;
}
}
}
In IIS, I've set up 2 websites.
S_Minio
binds to minio.mysite.com
rewrite rules
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectBrowsers" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" negate="false" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="false">
<add input="{HTTP_USER_AGENT}" pattern="*firefox*" />
<add input="{HTTP_USER_AGENT}" pattern="*edge*" />
<add input="{HTTP_USER_AGENT}" pattern="*chrome*" />
</conditions>
<action type="Redirect" url="https://console.minio.mysite.com/login" logRewrittenUrl="true" redirectType="Found" />
</rule>
<rule name="Docker reverse proxy for minio" enabled="true" stopProcessing="false">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="*console*" />
</conditions>
<action type="Rewrite" url="http://10.200.2.67:3009/{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
S_Minio_Console
binds to console.minio.mysite.com
rewrite rules
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Docker reverse proxy for minio console" enabled="true" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://10.200.2.67:30091/{R:1}" appendQueryString="true" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Up until this point, everything works well.
If I visit https://minio.mysite.com, I get redirected to https://console.minio.mysite.com.
I can log in to the console and view my files.
If I try to share a file, the following url gets generated: http://172.18.0.2:9000/test/my_excel_file.xlsx?query_strings_ommitied which is no good.
According to the things to consider section, I updated my docker-compose.yml file with the following changes
services:
minio_web2:
...
environment:
...
+ MINIO_SERVER_URL: https://minio.mysite.com
+ MINIO_BROWSER_REDIRECT_URL: https://console.minio.mysite.com
Now when I log in, I get a error Post "https://minio.mysite.com/": dial tcp: i/o timeout.
nginx and my rewrite rules have not changed and im not sure what to change from this point.

Related

convert from IIS rewrite to nginx

<?xml version="1.0" encoding="UTF-8"?>
<rules>
<clear />
<rule name="wfq2020">
<match url="^(auth|platform-admin|product|substation-admin)/(.*)" />
<action type="Rewrite" url="https://google.com/{R:0}" />
</rule>
<rule name="api.wfq2020">
<match url="^(wuneng-platform-web|wuneng-channel-web|wuneng-web|wuneng-user-web|mini-program)/(.*)" />
<action type="Rewrite" url="https://api.google.com/{R:0}" />
</rule>
</rules>
Here is my iis rule, I want to convert it to nginx rule, hope someone can help me!
I'm not super familiar with IIS rewrite, but I have checked their doc and it seems pretty close to NGINX.
On NGINX, is recommended to use return if possible (doc here). The {R:0} is similar to the NGINX vars, in this case, the $request_uri.
You can also combine with the ~*, this is a "Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching)" (doc here). The ^/... means that it needs to start with it (e.g. starts with /wuneng-platform-web and anything else after that (.*).
The code will be something like:
http {
## ...
server {
## ...
location ~* ^/(auth|platform-admin|product|substation-admin)(.*) {
return 301 https://google.com$request_uri;
}
location ~* ^/(wuneng-platform-web|wuneng-channel-web|wuneng-web|wuneng-user-web|mini-program)(.*) {
return 301 https://api.google.com$request_uri;
}
## ...
}
## ...
}
I hope this will help you out :)

IIS ARR Multiple ports

I'm having a hard time configuring the balance in IIS via ARR with multiple ports.
The difficulty is in working with different doors than the 80 and 443.
On the same server I have applications on port 80, 443 and 8080. I managed to make it work on port 80 and 443. When I add port 8080 it is redirected to port 443.
The structure is as follows:
IP PUBLIC:80 > IIS ARR > Private IP 1:80, PRIVATE IP 2:80
IP PUBLIC:443 > IIS ARR > Private IP 1:443, PRIVATE IP 2:443
IP PUBLIC:8080 > IIS ARR > Private IP 1:8080, PRIVATE IP 2:8080
The rules I have for url rewrite are:
Name: ARR_Serverfarm_loadbalance
- Match URL
Requested URL: Matches the Pattern
Using: Wildcard
Pattern: *
MArk: Ignore Case
- Action
Action type: Route to Server Farm
Scheme: http://
Server farm: serverfarm
Path: /{R:0}
Mark "Stop processing of subquent rules"
Other rule:
Name: Forward proxy
- Match URL
Requested URL: Does not match the Pattern
Using: Wildcards
Pattern: *
Mark: Ignore case
- Conditions
logical grouping: Match All
{HTTP_HOST} Match the Pattern *
- Action
Action type: Rewrite
Rewrite URL: http://{C:1}/{R:0}
Mark Append query string.
I appreciate the help.
I'll post the rule to make it clearer what I have today.
<rule name="ARR_serverfarm_loadbalance" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://serverfarm/{R:0}" />
</rule>
<rule name="forward proxy" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" negate="true" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="*" />
</conditions>
<action type="Rewrite" url="http://{C:1}/{R:0}" />
</rule>
</globalRules>
In summary, I couldn't configure port 80, 443 and 8080 on the same destination and ended up creating two different webfarms, one on 80 and 443 and another on 8080 and 8443.
After that as a final solution, I created conditions based on the URL.
Example:
<conditions trackAllCaptures = "true" >
<add input = "{URL}" pattern = "^/app1/( . *)"/> 
</conditions>

Client is not receiving event from SocketIO via IIS Node

I have a web application which is making a socket connection with a NodeJS server hosted via IIS Node. The connection seems to be made properly as I resolved a 404 polling error on the client that I was initially having. However now, it looks like the client is not receiving socket events from IIS Node.
My theory is that because IIS Node is acting like a proxy, the event sent back to the client is stopping somewhere at the IIS Node level.
exports.register = function(socket) {
User.schema.post('save', function (doc) {
console.log("Save socket");
onSave(socket, doc);
});
}
function onSave(socket, doc, cb) {
socket.emit('User List Update', doc);
}
In Node, the above event fires, but it is not received on the front end.
The client looks like this:
var socket = io.connect("http://myinternallyhostedserver:7777/reception");
socket.on('User List Update', function () {
console.log('Received socket event!');
if (vm.enableAlert) {
vm.alertSound.play();
}
vm.getUsers();
});
My web.config file looks like this:
<configuration>
<appSettings>
<add key="virtualDirPath" value="/reception" />
</appSettings>
<system.webServer>
<handlers>
<add name="iisnode" path="server/app.js" verb="*" modules="iisnode" />
</handlers>
<iisnode enableXFF="true" />
<webSocket enabled="false"/>
<rewrite>
<rules>
<rule name="reception">
<match url="/*" />
<action type="Rewrite" url="server/app.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Running all of this on my local machine works properly. Socket events are sent and received. Adding IIS Node into the workflow seems to be where it stopped working. Any help would be greatly appreciated.
While using socket.io with proxy pass , you need to pass some variable like upgrade etc. I didnt even try using iis to proxy pass socket.io but I came across some problem in apache proxy pass . Therefore I choose nginx to proxy server.
Maybe you need to write this kind of parameters in iis , alternatively you can use nginx as a proxy pass server.
location / {
proxy_pass http://socket_nodes_2/doSomething;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
upstream socket_nodes_2 {
server 192.168.1.155:1338;
server 192.168.1.156:1338;
}

IIS: Modify origin server in order to manage X-Forwarded-Host (XFH)

I need to do this in IIS but I do not know how.
Here is how it is done in Nginx and Apache:
Nginx:
location / {
if ( $http_x_forwarded_host = alias.example.com ) {
root /path/to/website/alias1/;
}
}
Apache:
RewriteEngine on
RewriteCond "%{HTTP:X-Forwarded-Host}" "alias\.example\.com" [NC]
RewriteRule "^(.*)$" "/sub/path/$1" [PT]
The examples are copied from: https://www.keycdn.com/support/manage-multiple-websites-with-one-zone/
The configuration you might need is very similar to this:
<rewrite>
<allowedServerVariables>
<add name="X-FORWARDED-HOST" />
</allowedServerVariables>
<rewriteMaps>
</rewriteMaps>
<globalRules>
<clear />
<rule name="HTTPS ReWrite" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="/sub/path/{R:1} />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_X_FORWARDED_HOST}" pattern="alias.example.com" />
</conditions>
</rule>
</globalRules>
</rewrite>

Reproducing IIS Reverse Proxy Config with nginx

I am trying to reproduce an IIS reverse proxy configuration with nginx. The application is for a mobile iphone app to communicate to a configuration server on our LAN. Both the mobile app and web server are third party and lack documentation.
web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Authenticate" stopProcessing="true">
<match url="^authenticate(.*)" />
<action type="Rewrite" url="http://INTERNALIP:80{R:1}" logRewrittenUrl="true" />
</rule>
<rule name="SAC" stopProcessing="true">
<match url="^sac(.*)" />
<action type="Rewrite" url="http://INTERNALIP:5447{R:1}" logRewrittenUrl="true" />
</rule>
<rule name="Config" stopProcessing="true">
<match url="^config(.*)" />
<action type="Rewrite" url="http://INTERNALIP:5449{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
After reading through the documentation and looking through other posts. I came up with this for my server directive.
nginx.conf
server {
listen 5600;
server_name mobile.example.com;
access_log /var/log/nginx/log/rproxy.log;
error_log /var/log/nginx/log/error.log;
location ^~ /authenticate(.*){
rewrite ^/authenticate(.*)/ /$1 break;
proxy_pass http://INTERNALIP;
}
location ^~ /sac(.*){
rewrite ^/sac(.*)/ /$1 break;
proxy_pass http://INTERNALIP:5447;
}
location ^~ /config(.*){
rewrite ^/config(.*)/ /$1 break;
proxy_pass http://INTERNALIP:5449;
}
}
I am seeing some data in the log, but it wasn't really what I was expecting and I'm having difficulties troubleshooting from here. I really wish I knew what the requests looked like and had some sort of request flow, but I do not.
access.log
xx.xx.xx.xx - - [24/Jan/2014:18:33:45 +0000] "\x16\x03\x01\x00\xA1\x01\x00\x00\x9D\x03\x01R\xE2\xB2\x09\xBC\x9F\xE4h\x04_\x8C\x0C[\x94\x1E\xE66H\x1DLY^H\x16\xF5U\xF4\xF8" 400 172 "-" "-"
xx.xx.xx.xx - - [24/Jan/2014:18:33:45 +0000] "\x16\x03\x01\x00\xA1\x01\x00\x00\x9D\x03\x01R\xE2\xB2\x09\xD8>e\x15\x89\xF1\xC1,\xC6_Qj\x96\x88\xC8\x11\x06P=\xB2OE\xB6\xA4,\xE7;/\x00\x00J\x00\xFF\xC0$\xC0#\xC0" 400 172 "-" "-"
xx.xx.xx.xx - - [24/Jan/2014:18:33:45 +0000] "\x16\x03\x00\x00E\x01\x00\x00A\x03\x00R\xE2\xB2\x09\x09\xEC(\xCE\xD3\xB7$\xA7T\x0C\xEA\xEF^0\xF9In*Y#\xFE\x9F\x09\xD3W\xA8)f\x00\x00\x1A\x00\xFF\x00=\x00<\x00/\x00\x05\x00\x04\x005\x00" 400 172 "-" "-"
Any help would be greatly appreciated.
Thanks
I found this question searching for "\x16\x03\x01\x00", which I was also seeing throughout my access.log and not understanding what it was I was looking at. It's raw ssl coming through. For me, I had http redirecting to https but my server definition looked like
server {
listen 443;
server_name my.server.com;
...
}
I fixed the problem by adding in the missing "default ssl" to the listen line.
server {
listen 443 default ssl;
server_name my.server.com;
...
}

Resources