Artifactory remove /api/gems/gems from url with nginx - nginx

I have an Artifactory server as a gem repository. In order to use the local server I need to setup my gem sources with this ugly url.
gem source -a gems.example.com/api/gems/gems/
I'd like to remove the need for developers to know the URI /api/gems/gems/ so they can simply access gems.example.com
server {
listen *:443 ssl default;
server_name artifactory.example.com gems.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/artifactory.example.com.crt.pem;
ssl_certificate_key /etc/ssl/private/artifactory.example.com.key.pem;
location / {
if ( $request_uri ~ ^/(.*)$ ) { proxy_pass http://localhost:8081/artifactory/$1; }
proxy_cookie_path ~*^/.* /;
proxy_pass http://localhost:8081/artifactory/;
proxy_pass_header Server;
proxy_read_timeout 2400s;
}
A rewrite would work, however the nginx configs already have the following if, and nginx does not allow for multiple conditionals.
not valid:
if ( $request_uri ~ ^/(.*)$ && $server_name) { proxy_pass http://localhost:8081/artifactory/$1; }
How can I eliminate /api/gems/gems/ from the url https://gems.example.com/api/gems/gems/ ?

Use multiple server blocks like so:
Note that the second server block has the following changes.
- server_name
- no 'default' on the listen line
- proxy_pass http://localhost:8081/artifactory/api/gems/gems/
/etc/nginx/sites-enabled/artifactory.conf
server {
listen *:443 ssl default;
server_name artifactory.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/artifactory.example.com.crt.pem;
ssl_certificate_key /etc/ssl/private/artifactory.example.com.key.pem;
location / {
if ( $request_uri ~ ^/(.*)$ ) { proxy_pass http://localhost:8081/artifactory/$1; }
proxy_cookie_path ~*^/.* /;
proxy_pass http://localhost:8081/artifactory/;
proxy_pass_header Server;
proxy_read_timeout 2400s;
}
# ....
/etc/nginx/sites-enabled/artifactory-gems.conf
server {
listen *:443 ssl;
server_name gems.example.com;
ssl on;
ssl_certificate /etc/ssl/certs/artifactory.example.com.crt.pem;
ssl_certificate_key /etc/ssl/private/artifactory.example.com.key.pem;
location / {
if ( $request_uri ~ ^/(.*)$ ) { proxy_pass http://localhost:8081/artifactory/api/gems/gems/$1; }
proxy_cookie_path ~*^/.* /;
proxy_pass http://localhost:8081/artifactory/api/gems/gems/;
proxy_pass_header Server;
proxy_read_timeout 2400s;
}
# ....
Note /gems/gems corresponds to the virtual repo on artifactory called 'gems'. If you have multiple gem repositories, you will need to add a vhost for every repo.

Related

How to mask sub-domain using nginx

I have nodejs application working with a main domain, and its connecting thought nginx proxy pass to nodejs application, with redirection rule , as per the redirection rule if request is coming from mobile, it will redirect into a sub-domain, it is working fine.
both main domain and sub-domain are different version ,and running deferent server.
Now I want to mask this sub-domain , I don't want to see my sub-domain in browser, how can I do this.
Below mentioned my nginx conf.
server {
listen 80;
server_name mydomain;
return 301 https://$server_name$request_uri;
}
include mime.types;
server {
listen 443 ssl;
server_name mydomain;
ssl_certificate /etc/ssl/CA_Bundle.ca-bundle;
ssl_certificate_key /etc/ssl/2021/server.key;
location / {
add_header Access-Control-Allow-Origin *;
proxy_set_header Host $host;
proxy_pass http://172.17.0.1:8080;
proxy_redirect off;
expires off;
set $agentflag 0;
if ( $http_user_agent ~* "(Mobile)" ){
set $agentflag 1;
}
if ($request_uri ~ "user-agent"){
set $agentflag 0;
}
if ( $agentflag = 1 ) {
rewrite ^/(.*)/$ /$1 permanent;
return 307 https://mobile.mydomain$request_uri;
}
}
}
server {
listen 80;
server_name mobile.mydomain;
return 301 https://$server_name$request_uri;
}
include mime.types;
server {
listen 443 ssl;
server_name mobile.mydomain;
ssl_certificate /etc/ssl/CA_Bundle.ca-bundle;
ssl_certificate_key /etc/ssl/2021/server.key;
location / {
add_header Access-Control-Allow-Origin *;
proxy_set_header Host $host;
proxy_pass http://172.17.22.1:8081;
proxy_redirect off;
expires off;
}
}
It is working fine now,
I have used proxy_pass , instead of rewrite.
if ( $agentflag = 1 ) {
proxy_pass http://IP-address-mobile-app;

nginx The page isn’t redirecting properly, how to fix?

my nginx conf, goal to make all not https to https, and from www to not www, make by few tutorials by i got this all the time
The page isn’t redirecting properly
An error occurred during a connection to example.com.
This problem can sometimes be caused by disabling or refusing to
accept cookies.
.
server {
listen 80;
server_name "~^www\.(.*)$" ;
return 301 https://example.com$request_uri ;
}
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate pathto/fullchain.pem;
ssl_certificate_key pathto/privkey.pem;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl on;
ssl_certificate pathto/fullchain.pem;
ssl_certificate_key pathto/privkey.pem;
ssl_trusted_certificate pathto/chain.pem;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=31536000";
add_header X-Frame-Options "SAMEORIGIN";
client_max_body_size 4G;
location /static/ {
alias /asd/ads/static/;
}
location /media/ {
alias /asd/ads/media/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
}
}
It looks like your post is mostly code; please add some more details.
i remove from my django settings
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
And it work!!!

the redirect from http to https does not work in nginx

I am trying to redirect all the http traffic to https and my nginx conf looks like this:
upstream upstreamServer {
server upstream_serv:80;
}
server {
listen 80;
server_name ~^(([a-zA-Z0-9]+)|)test\.xy\.abc\.io$ ;
access_log /var/log/nginx/access.log backend;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name ~^(([a-zA-Z0-9]+)|)test\.xy\.abc\.io$ ;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_certificate /path/to/cert_chain.pem;
ssl_certificate_key /path/to/cert_key.pem;
ssl_trusted_certificate /path/to/cert_chain.pem;
access_log /var/log/nginx/access.log backend;
# Redirect all traffic in /.well-known/ to lets encrypt
location /.well-known/acme-challenge/ {
root /var/tmp;
index index.html index.htm;
}
location / {
proxy_pass http://upstreamServer;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_buffering off;
if ($uri ~* ".(js|png|jpg|jpeg|svg|gif|avi|mp3|mp4)$" ){
expires 1d;
add_header Cache-Control public;
}
proxy_pass_request_headers on;
}
}
But for some reason it doesn't work. I read about how the nginx chooses the server block and location block. The setup looks correct to me according to what I understand but still the site keeps loading on http when I hit the url http://test.xy.abc.io instead of redirecting me to https.
I also tried using only
return 301 https://$host$request_uri;
instead of
location / {
return 301 https://$host$request_uri;
}
but it doesn't work either.
Did I get right that your page is still loading the unencrypted http version? Did you reaload the service to load the changed config file? (sorry to ask that stupid question back)
nginx -t && nginx -s reload
I personally use in all nginx instances I maintain something like this:
server {
listen 80 default_server;
# no server_name means all
# For let's encrypt domains: .well-known/acme-challenge
location '/.well-known/acme-challenge' {
default_type "text/plain";
root /var/www/certbot;
}
# Redirect http -> https.
location / {
return 301 https://$host$request_uri$is_args$args;
}
}
The problem was there is a GCP loadbalancer before my nginx proxy. Which was forwarding all the requests on https to my nginx proxy no matter if the orignal reuquest was http or https. After searching the internet I found that loadbalancer can not force https on clients. So this what I had to do in my nginx location block.
if ($http_x_forwarded_proto = http) {
return 301 https://$host$request_uri;
}
and the complete solution looks like this:
server {
listen 80;
listen 443 ssl;
server_name ~^(([a-zA-Z0-9]+)|)test\.xy\.abc\.io$ ;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_certificate /path/to/cert_chain.pem;
ssl_certificate_key /path/to/cert_key.pem;
ssl_trusted_certificate /path/to/cert_chain.pem;
access_log /var/log/nginx/access.log backend;
# Redirect all traffic in /.well-known/ to lets encrypt
location /.well-known/acme-challenge/ {
root /var/tmp;
index index.html index.htm;
}
location / {
if ($http_x_forwarded_proto = http) {
return 301 https://$host$request_uri;
}
proxy_pass http://upstreamServer;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_buffering off;
if ($uri ~* ".(js|png|jpg|jpeg|svg|gif|avi|mp3|mp4)$" ){
expires 1d;
add_header Cache-Control public;
}
proxy_pass_request_headers on;
}
}

Nginx : File Not found inside directory ( though file exists ) .. On Root directory it works fine

On my server I have few files in /var/www and few in /var/www/static ..
wget http://localhost/static/404.html
etc. works fine.
If I create a new file suppose test.html in /var/www
wget http://localhost/test.html
works fine.
If I create a new file suppose test.html in /var/www/static
wget http://localhost/static/test.html NOT WORKS FINE.
I tried restarting nginx; nginx access logs just says 404. Any clue !
default file in sites-enabled:
upstream backend {
server localhost:8080;
# maximum number of idle connections to each upstream server
keepalive 20;
}
map $http_x_forwarded_proto $proxy_scheme {
default $scheme;
https https;
}
server {
listen 80;
listen 443 ssl;
server_name localhost;
root /var/www;
resolver 10.0.0.2;
ssl_certificate cert.pem;
ssl_certificate_key private-key.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
set $mweb false;
if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino") {
set $mweb true;
}
if ($http_user_agent ~* "^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-)") {
set $mweb true;
}
if ($http_host = "crm.qa.hopscotch.in") {
set $mweb false;
}
if ($http_cookie ~ 'desktop_site=true') {
set $mweb false;
}
location / {
if ($http_host = "qa.hopscotch.in") {
rewrite ^ $proxy_scheme://www.qa.hopscotch.in$request_uri? permanent;
}
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_scheme;
proxy_set_header Host $http_host:$server_port;
proxy_http_version 1.1;
proxy_set_header Connection "";
if ($mweb = true) {
set $mweb_elb "$proxy_scheme://m.qa.hopscotch.in";
proxy_pass $mweb_elb;
break;
}
proxy_pass http://backend;
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
All your requests are proxied to localhost at port 8080 - whatever runs there decides what to serve. A simple location block to just serve any files it finds in the directory would be:
location / {
try_files $uri =404;
}
This will return a file if it is found, or a http 404 error if the file could not be found.
By the way, using so many if statements is maybe not a good idea, because it hurts nginx performance. I have never used an if statement in my configs, because it is usually not worth it and also discouraged by nginx documentation.

Nginx: WebSocket wildcard location

I use a nginx instance in front of a Go service.
I want to redirect anything on port 80 to https. [done]
All (non-websocket) https requests at /* should go to https://localhost:8443/* [done]
All websocket https requests at /ws/* should go to https://localhost:8443/ws/* [missing]
My current config:
ssl_certificate ...
ssl_certificate_key ...
ssl_ciphers ...
ssl_prefer_server_ciphers on;
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name www.mydomain.com mydomain.com;
add_header Strict-Transport-Security "max-age=31536000";
location /ws { <--- This only works for /ws but not /ws/app1
proxy_pass http://localhost:8443/ws;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / { <--- Catches anything, even without wildcard ?!
proxy_pass http://localhost:8443;
}
}
server {
listen 443 ssl;
server_name *.mydomain.com;
return 444;
}
Why is this necessary ? Well, as I understand, you have to set the upgrade headers explicitly, so I guess you have to specify another location.
Ideally, I would just use one location, but then websockets are blocked (because upgrade headers never make it to the Go service...)
I'm not a nginx expert, so bear with me =).
[EDIT]
I got it working now. I'm not sure if its ok to always set_header Upgrade/Connection, even if it's not a websocket request, but my Go service doesn't give a ****, so it works for me =]
ssl_certificate ...
ssl_certificate_key ...
ssl_ciphers ...
ssl_prefer_server_ciphers on;
server {
listen 80;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name www.mydomain.com mydomain.com;
add_header Strict-Transport-Security "max-age=31536000";
location / { <--- Catches anything, even without wildcard ?!
proxy_pass http://localhost:8443;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server {
listen 443 ssl;
server_name *.mydomain.com;
return 444;
}
Check out the article at https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
You are not using any location_match, so the match is a prefix match.
Use ~ as the location match modifier to have it interpreted as a regular expression.
The line location /ws should match every query starting with /ws.

Resources