I'm trying to make a https proxy on nginx engine. And when I test it on different sites - I always get two HTTP codes - 302 - redirect to https scheme and 400 after connect
proxy config
server {
error_log /var/log/nginx/nginx.err;
access_log /var/log/nginx/nginx.acc;
resolver 127.0.0.53;
listen 80; #default_server;
listen 443 ssl default_server;
server_name proxy;
ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem;
proxy_ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem;
proxy_ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem;
proxy_ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem;
large_client_header_buffers 1 128k;
proxy_ssl_verify on;
proxy_ssl_session_reuse off;
ssl_verify_client off;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers RC4:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Access-Control-Allow-Origin *;
proxy_buffering on;
proxy_buffers 8 16k;
proxy_buffer_size 16k;
proxy_pass http://$host$request_uri;
proxy_read_timeout 1800;
}
}
curl -x localhost:80 goo.gl -I -L output (goo.gl - for example, but I have this issue for every site)
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 10 Sep 2021 12:32:42 GMT
Content-Type: application/binary
Content-Length: 0
Connection: keep-alive
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Location: https://goo.gl/
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
HTTP/1.1 400 Bad Request
Server: nginx/1.18.0 (Ubuntu)
Date: Fri, 10 Sep 2021 12:32:42 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
same curl output with -v
* Trying ::1:80...
* TCP_NODELAY set
* connect to ::1 port 80 failed: Connection refused
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#0)
> HEAD http://goo.gl/ HTTP/1.1
> Host: goo.gl
> User-Agent: curl/7.68.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Server: nginx/1.18.0 (Ubuntu)
Server: nginx/1.18.0 (Ubuntu)
< Date: Fri, 10 Sep 2021 12:34:02 GMT
Date: Fri, 10 Sep 2021 12:34:02 GMT
< Content-Type: application/binary
Content-Type: application/binary
< Content-Length: 0
Content-Length: 0
< Connection: keep-alive
Connection: keep-alive
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
Pragma: no-cache
< Expires: Mon, 01 Jan 1990 00:00:00 GMT
Expires: Mon, 01 Jan 1990 00:00:00 GMT
< Location: https://goo.gl/
Location: https://goo.gl/
< X-XSS-Protection: 0
X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'https://goo.gl/'
* Hostname localhost was found in DNS cache
* Trying ::1:80...
* TCP_NODELAY set
* connect to ::1 port 80 failed: Connection refused
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 80 (#1)
* allocate connect buffer!
* Establish HTTP proxy tunnel to goo.gl:443
> CONNECT goo.gl:443 HTTP/1.1
> Host: goo.gl:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
< Server: nginx/1.18.0 (Ubuntu)
Server: nginx/1.18.0 (Ubuntu)
< Date: Fri, 10 Sep 2021 12:34:02 GMT
Date: Fri, 10 Sep 2021 12:34:02 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 166
Content-Length: 166
< Connection: close
Connection: close
<
* Received HTTP code 400 from proxy after CONNECT
* CONNECT phase completed!
* Closing connection 1
curl: (56) Received HTTP code 400 from proxy after CONNECT
If I do curl without a proxy, then it will contain messages with successful TLS handshakes
Related
Help with ACME HTTP01 Let's Encrypt challenge please.
i'm trying to get certificate for domain behind proxy.
my config:
upstream kube-ingress-https {
# The least number of active connections
least_conn;
server 172.22.16.3:443 max_fails=1 fail_timeout=300;
}
server {
listen 443;
proxy_protocol on;
proxy_pass kube-ingress-https;
}
my scheme: WORLD ====> NGINX (reverse proxy) ==============> K8S ingress(cert manager)
cert-manager shows: Waiting for HTTP-01 challenge propagation: wrong status code '502', expected '200'
curl -I -k https://k8s-dash.domain.kz/.well-known/acme-challenge/pXy1kENDkrXpGNKLeyCc8huIfgUILzjErxiYhj80mxI
HTTP/2 502
date: Fri, 21 Oct 2022 06:55:51 GMT
content-type: text/html
content-length: 150
strict-transport-security: max-age=15724800; includeSubDomains
access-control-allow-origin: *
access-control-allow-credentials: true
curl -I -k https://k8s-dash.mydomain.kz
HTTP/2 200
date: Fri, 21 Oct 2022 06:55:58 GMT
content-type: text/html; charset=utf-8
content-length: 1338
accept-ranges: bytes
cache-control: no-cache, no-store, must-revalidate
last-modified: Fri, 15 Oct 2021 07:41:12 GMT
strict-transport-security: max-age=15724800; includeSubDomains
access-control-allow-origin: *
access-control-allow-credentials: true
i've found a solution:
i've delete ingress annotation: acme.cert-manager.io/http01-edit-in-place: "true"
I am running nginx version: nginx/1.20.2 onCentOS Linux release 7.9.2009 (Core) as reverse proxy. I have added the below line in main context of /etc/nginx/nginx.conf config file
cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
load_module modules/ngx_http_cache_purge_module.so;
events {
worker_connections 1024;
}
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;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
nginx -t -c /etc/nginx/nginx.conf
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
location / {
add_header Access-Control-Allow-Origin *;
proxy_pass http://127.0.0.1:8080;
proxy_cache_purge PURGE from 127.0.0.1 36.115.171.121 14.18.155.4;
#proxy_cache_bypass $bypass;
# configure proxy-cache-purge
#proxy_cache_purge PURGE from 0.0.0.0;
proxy_http_version 1.1;
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_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_hide_header X-Powered-By;
proxy_hide_header X-Generator;
proxy_hide_header X-Drupal-Cache;
proxy_hide_header X-Drupal-Dynamic-Cache;
proxy_hide_header Server;
proxy_store_access group:rw;
#page caching configuration
proxy_ignore_headers Vary;
proxy_ignore_headers Set-Cookie;
proxy_cache testnginx;
proxy_cache_key $scheme$request_method$proxy_host$request_uri;
The nginx cache has the contents which are as follows.
# pwd
/var/www/nginx/cache
#
# ls -l
total 0
drwxrwxrwx. 14 nginx deployuser 114 May 8 05:58 content
drwxrwxrwx. 15 nginx deployuser 123 May 8 07:31 files
#
/var/www/nginx/cache/files
# ls -l
total 0
drwx------ 4 nginx nginx 26 May 8 05:58 0
drwx------ 4 nginx nginx 26 May 8 06:04 1
drwx------ 5 nginx nginx 36 May 8 05:58 2
drwx------ 3 nginx nginx 16 May 6 12:12 3
drwx------ 4 nginx nginx 26 May 8 05:58 4
drwx------ 3 nginx nginx 16 May 8 06:04 6
drwx------ 3 nginx nginx 16 May 8 06:04 7
drwx------ 3 nginx nginx 16 May 5 10:44 9
drwx------ 3 nginx nginx 16 May 5 10:44 a
drwx------ 3 nginx nginx 16 May 8 06:04 b
drwx------ 3 nginx nginx 16 May 8 07:31 d
drwx------ 4 nginx nginx 26 May 8 06:04 e
drwx------ 3 nginx nginx 16 May 5 11:29 f
# cd ../content/
# ls -l
total 0
drwx------ 3 nginx nginx 16 May 6 05:28 1
drwx------ 5 nginx nginx 36 May 8 11:39 2
drwx------ 3 nginx nginx 16 May 6 12:12 3
drwx------ 3 nginx nginx 16 May 8 05:58 4
drwx------ 6 nginx nginx 46 May 5 08:03 5
drwx------ 6 nginx nginx 46 May 8 07:31 7
drwx------ 4 nginx nginx 26 May 5 08:03 8
drwx------ 3 nginx nginx 16 May 4 17:21 9
drwx------ 4 nginx nginx 26 May 8 06:04 a
drwx------ 5 nginx nginx 36 May 8 06:30 c
drwx------ 3 nginx nginx 16 May 5 06:21 d
drwx------ 4 nginx nginx 26 May 5 08:03 f
#
When i run using PURGE Method the http response is 404 not found whereas when i run using GET Method the http response is 200 OK
400 Not Found
#curl -vvv -X PURGE -I https://testnginxproxycachepurge.testintcraft.com/apis
* About to connect() to testnginxproxycachepurge.testintcraft.com port 443 (#0)
* Trying 34.105.141.181...
* Connected to testnginxproxycachepurge.testintcraft.com (34.105.141.181) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=testnginxproxycachepurge.testintcraft.com
* start date: Apr 26 11:06:35 2022 GMT
* expire date: Jul 25 11:06:34 2022 GMT
* common name: testnginxproxycachepurge.testintcraft.com
* issuer: CN=R3,O=Let's Encrypt,C=US
> PURGE /apis HTTP/1.1
> User-Agent: curl/7.29.0
> Host: testnginxproxycachepurge.testintcraft.com
> Accept: */*
>
< HTTP/1.1 404 Not Found
HTTP/1.1 404 Not Found
< Server: nginx/1.20.2
Server: nginx/1.20.2
< Date: Sun, 08 May 2022 08:01:55 GMT
Date: Sun, 08 May 2022 08:01:55 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 153
Content-Length: 153
< Connection: keep-alive
Connection: keep-alive
<
* Excess found in a non pipelined read: excess = 153 url = /apis (zero-length body)
* Connection #0 to host testnginxproxycachepurge.testintcraft.com left intact
200 OK
#curl -vvv -X GET -I https://testnginxproxycachepurge.testintcraft.com/apis
* About to connect() to testnginxproxycachepurge.testintcraft.com port 443 (#0)
* Trying 34.105.141.181...
* Connected to testnginxproxycachepurge.testintcraft.com (34.105.141.181) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=testnginxproxycachepurge.testintcraft.com
* start date: Apr 26 11:06:35 2022 GMT
* expire date: Jul 25 11:06:34 2022 GMT
* common name: testnginxproxycachepurge.testintcraft.com
* issuer: CN=R3,O=Let's Encrypt,C=US
> GET /apis HTTP/1.1
> User-Agent: curl/7.29.0
> Host: testnginxproxycachepurge.testintcraft.com
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.20.2
Server: nginx/1.20.2
< Date: Sun, 08 May 2022 08:01:43 GMT
Date: Sun, 08 May 2022 08:01:43 GMT
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive
< Cache-Control: max-age=21600, public
Cache-Control: max-age=21600, public
< Link: <https://testnginxproxycachepurge.testintcraft.com/apis>; rel="canonical"
Link: <https://testnginxproxycachepurge.testintcraft.com/apis>; rel="canonical"
< X-UA-Compatible: IE=edge
X-UA-Compatible: IE=edge
< Content-language: en
Content-language: en
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< Permissions-Policy: interest-cohort=()
Permissions-Policy: interest-cohort=()
< Expires: Sun, 19 Nov 1978 05:00:00 GMT
Expires: Sun, 19 Nov 1978 05:00:00 GMT
< Vary: Cookie
Vary: Cookie
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< Strict-Transport-Security: max-age=31536000; includeSubDomains
Strict-Transport-Security: max-age=31536000; includeSubDomains
< Set-Cookie: ADRUM_BT=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Set-Cookie: ADRUM_BT=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
< Set-Cookie: ADRUM_BT=R%3A53%7Cg%3A5277dd0a-8de6-440a-a8f7-52fb782db251139%7Cn%3Aicebergtest_e1c60ae6-5d00-47d5-8c0a-690d8465795f; expires=Sun, 08-May-2022 05:58:56 GMT; Max-Age=30; path=/
Set-Cookie: ADRUM_BT=R%3A53%7Cg%3A5277dd0a-8de6-440a-a8f7-52fb782db251139%7Cn%3Aicebergtest_e1c60ae6-5d00-47d5-8c0a-690d8465795f; expires=Sun, 08-May-2022 05:58:56 GMT; Max-Age=30; path=/
< Last-Modified: Tue, 26 Apr 2022 14:39:40 GMT
Last-Modified: Tue, 26 Apr 2022 14:39:40 GMT
< ETag: "1650983980"
ETag: "1650983980"
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< X-Cache-Status: HIT
X-Cache-Status: HIT
<
* Excess found in a non pipelined read: excess = 15395 url = /apis (zero-length body)
* Connection #0 to host testnginxproxycachepurge.testintcraft.com left intact
#
Please guide me.
I want to use nginx as internet out proxy.
So, I try to connect to http://mirror01.org/google.com, but cache files were not created.
If I delete rewrite rule and replace proxy_pass to http://google.come cache files will be created.
Where did I go wrong?
Trace using curl
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.20.2
Date: Tue, 08 Mar 2022 15:44:42 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://google.com
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Tue, 08 Mar 2022 15:44:42 GMT
Expires: Thu, 07 Apr 2022 15:44:42 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
HTTP/1.1 200 OK
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Date: Tue, 08 Mar 2022 15:44:43 GMT
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Expires: Tue, 08 Mar 2022 15:44:43 GMT
Cache-Control: private
Set-Cookie: 1P_JAR=2022-03-08-15; expires=Thu, 07-Apr-2022 15:44:43 GMT; path=/; domain=.google.com; Secure
Set-Cookie: NID=511=21PQ3ziwDTFTppHDMUoAVReBsFB6oGkVHqT38eqJO25UQkP3SJSEleOsHhefVDR_TgKSK6DpcTmBewjKC-kazv8mWRrfW10NUJevh16H5MZtKrKCJxllfI4r; expires=Wed, 07-Sep-2022 15:44:43 GMT; path=/; domain=.google.com; HttpOnly
Nginx conf:
access_log /opt/nginx/log/access.log main;
error_log /opt/nginx/log/error.log crit;
proxy_cache_path /opt/nginx/cache levels=1:2 keys_zone=default_cache:10m max_size=2g
inactive=120m use_temp_path=off;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid any 60m;
server {
listen 80;
server_name mirror01.org;
location / {
proxy_cache default_cache;
proxy_buffering on;
proxy_ignore_headers Expires;
proxy_ignore_headers X-Accel-Expires;
proxy_ignore_headers Cache-Control;
proxy_ignore_headers Set-Cookie;
proxy_hide_header X-Accel-Expires;
proxy_hide_header Expires;
proxy_hide_header Cache-Control;
proxy_hide_header Pragma;
add_header X-Proxy-Cache $upstream_cache_status;
rewrite ^/(.*)$ http://$request_uri? break;
proxy_pass $request_uri;
}
}
I have an mywebsite.conf that is included in the nginx.conf. The file is like this:
server {
listen 80;
server_name www.mywebsite.nl;
return 301 https://www.mywebsite.nl$request_uri;
}
server {
listen 80;
server_name mywebsite.nl;
return 301 https://www.mywebsite.nl$request_uri;
}
server {
listen 443 ssl;
server_name mywebsite.nl;
...
return 301 https://www.mywebsite.nl$request_uri;
}
server {
listen 443 ssl http2;
server_name www.mywebsite.nl;
...
}
This config works for all of my websites. But somehow this time the http://mywebsite.nl does not redirect to https://www.mywebsite.nl.
I can't find out why. DNS is pointing to the server. Caches are incognito.
I reloaded and restarted nginx. Tried fresh browsers. Used https://wheregoes.com to test it.
Any ideas?
The output of curl is:
* Trying 37.97.xxx.xx...
* TCP_NODELAY set
* Connected to mywebsite.nl (37.97.xxx.xx) port 80 (#0)
> HEAD / HTTP/1.1
> Host: mywebsite.nl
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
< Date: Wed, 14 Jul 2021 05:55:03 GMT
Date: Wed, 14 Jul 2021 05:55:03 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 612
Content-Length: 612
< Last-Modified: Wed, 17 Apr 2019 18:42:45 GMT
Last-Modified: Wed, 17 Apr 2019 18:42:45 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: "5cb773a5-264"
ETag: "5cb773a5-264"
< Accept-Ranges: bytes
Accept-Ranges: bytes
I'm trying to configure Location directive on my nginx web-server (Ubuntu).
I can have access to:
http://127.0.0.1/app1/
BUT when I'm trying to get access whitout slash in the end like:
http://127.0.0.1/app1
I get an error 301 HTTP1.1/Moved permanently
I have following nginx config:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Looks like everything is OK.
And following default.conf:
server {
listen 80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /app1/ {
root /var/www/html/;
index index.html;
try_files $uri $uri/ /app1/index.html;
}
}
Curl output
http://127.0.0.1/app1/
root#ubuntu-test:/etc/nginx/sites-available# curl 127.0.0.1/app1/ -Iv
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /app1/ HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 20 Feb 2020 09:14:12 GMT
Date: Thu, 20 Feb 2020 09:14:12 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 5
Content-Length: 5
< Last-Modified: Tue, 18 Feb 2020 10:49:53 GMT
Last-Modified: Tue, 18 Feb 2020 10:49:53 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: "5e4bc151-5"
ETag: "5e4bc151-5"
< Accept-Ranges: bytes
Accept-Ranges: bytes
<
* Connection #0 to host 127.0.0.1 left intact
http://127.0.0.1/app1
root#ubuntu-test:/etc/nginx/sites-available# curl 127.0.0.1/app1 -Iv
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /app1 HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
HTTP/1.1 301 Moved Permanently
< Server: nginx/1.14.0 (Ubuntu)
Server: nginx/1.14.0 (Ubuntu)
< Date: Thu, 20 Feb 2020 09:19:31 GMT
Date: Thu, 20 Feb 2020 09:19:31 GMT
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 194
Content-Length: 194
< Location: http://127.0.0.1/app1/
Location: http://127.0.0.1/app1/
< Connection: keep-alive
Connection: keep-alive
Why does it happen?
Nginx selects the location / block to process the URI /app1 as no other locations are a better match. See how Nginx processes a request.
The $uri/ term of the try_files statement informs Nginx to append a / to any URI that matches a directory. The directory /var/www/html/app1 matches this requirement, so a 301 redirection is generated to append a / to the URI. See this document for details.
In addition, the default behaviour for a URI which ends with a / and points to a directory is to search that directory for a file that matches the index directive. See this document for details.
It is possible to deviate from this default behaviour, but you will need to make a number of changes to your configuration. The location /app1/ needs to lose the trailing / if you want it to match /app1. Your try_files directives need to lose the $uri/ term, if you want to avoid the 301 redirect. You will also lose default index processing, so the index directive will be useless.