Reverse proxy with NGINX (AMZ Linux 2) + NAT instance
Install nginx
sudo amazon-linux-extras install nginx1
nginx -v
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx
sudo systemctl is-enabled nginx
Configure reverse proxy
Reverse proxy for EC2:
HTTP:
cd /etc/nginx/conf.d
nano reverse-proxy.conf
Add following lines:
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass <http://172.31.18.252>;
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;
}
}
Check configure syntax and restart nginx:
nginx -t
systemctl restart nginx
HTTPS:
Generate key
openssl genrsa -aes128 2048 > server.key
openssl rsa -in server.key -out server.key
openssl req -new -key server.key > server.csr
※以下入力(このあたりは自由です。)
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:Tokyo
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# 証明書作成
openssl x509 -req -days 3650 -signkey server.key < server.csr > server.crt
mkdir /etc/nginx/ssl/
cp server.key server.crt /etc/nginx/ssl/
chmod 400 /etc/nginx/ssl/server.*
cd /etc/nginx/conf.d
nano proxy-ssl.conf
Add the following lines:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "ssl/server.crt";
ssl_certificate_key "ssl/server.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
location / {
proxy_pass <http://172.31.18.252;
}
}
nginx -t
systemctl restart nginx
Testing:
Create a private instance an
Install apache httpd and edit index
Connect to the private instance by public IP of reverse instance:
Before:
After:
Reference: https://www.server-world.info/en/note?os=CentOS_8&p=nginx&f=8
Stream for RDS
Reference: https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/
Install stream modules:
yum install nginx-mod-stream
Get IP of the RDS instance:
dig <name>.cluster-ro-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
For eg:
dig database-2.cluster-ro-cfvulhssfv2n.ap-northeast-1.rds.amazonaws.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> database-2.cluster-ro-cfvulhssfv2n.ap-northeast-1.rds.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7564
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;database-2.cluster-ro-cfvulhssfv2n.ap-northeast-1.rds.amazonaws.com. IN A
;; ANSWER SECTION:
database-2.cluster-ro-cfvulhssfv2n.ap-northeast-1.rds.amazonaws.com. 5 IN CNAME database-2-instance-1.cfvulhssfv2n.ap-northeast-1.rds.amazonaws.com.
database-2-instance-1.cfvulhssfv2n.ap-northeast-1.rds.amazonaws.com. 5 IN A 172.31.5.49
;; Query time: 4 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Nov 22 08:58:46 UTC 2022
;; MSG SIZE rcvd: 161
\=> IP of the DB instance: 172.31.5.49
Add following into nginx.conf file: (note that steam block has equal incident with http block):
stream {
upstream rds {
server 172.31.5.49:5432;
}
server {
listen 5432;
proxy_pass rds;
}
}
nginx -t
systemctl restart nginx
You can access the rds instance by the public IP of the proxy instnance
Reference: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ConnectToPostgreSQLInstance.html
Stream for Elasticache:
dig test-proxy-001.ndzcu2.ng.0001.apne1.cache.amazonaws.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> test-proxy-001.ndzcu2.ng.0001.apne1.cache.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test-proxy-001.ndzcu2.ng.0001.apne1.cache.amazonaws.com. IN A
;; ANSWER SECTION:
test-proxy-001.ndzcu2.ng.0001.apne1.cache.amazonaws.com. 15 IN CNAME test-proxy-001-001.ndzcu2.0001.apne1.cache.amazonaws.com.
test-proxy-001-001.ndzcu2.0001.apne1.cache.amazonaws.com. 15 IN A 172.31.32.145
;; Query time: 4 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Tue Nov 22 09:52:46 UTC 2022
;; MSG SIZE rcvd: 140
→ IP = 172.31.32.145
stream {
upstream elasticache {
server 172.31.32.145:6379;
}
server {
listen 6379;
proxy_pass elasticache;
}
}
nginx -t
systemctl restart nginx
Reference: https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/GettingStarted.ConnectToCacheNode.html
Testing:
Download the CLI: https://github.com/microsoftarchive/redis/releases/download/…
Extract, and open terminal:
C:\Users\trinhthihaiyen\Downloads\Redis-x64-3.0.504>redis-cli.exe -h 52.197.101.143 -p 6379
Could not connect to Redis at 52.197.101.143:6379: Unknown error
not connected> ^C
C:\Users\trinhthihaiyen\Downloads\Redis-x64-3.0.504>redis-cli.exe -h 52.197.101.143 -p 6379
52.197.101.143:6379> set a "hello"
OK
52.197.101.143:6379> get a
"hello"
52.197.101.143:6379>
File configure:
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
# update IP in the stream configuration to your IP
stream {
upstream elasticache {
server 172.31.32.145:6379;
}
server {
listen 6379;
proxy_pass elasticache;
}
upstream rds {
server 172.31.5.49:5432;
}
server {
listen 5432;
proxy_pass rds;
}
}
Reverse proxy for Elasticsearch
cd /etc/nginx/conf.d
nano es-proxy.conf
Add the following lines:
server {
listen 443 ssl;
server_name $host;
rewrite ^/$ https://$host/_dashboards redirect;
ssl_certificate "ssl/server.crt";
ssl_certificate_key "ssl/server.key";
#ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
location ^~ /_dashboards {
# Forward requests to Dashboards
# proxy_pass https://vpc-workshop-domain-vpc-sanhsxgdhgmlm3ipovjzmbivse.us-east-1.es.amazonaws.com/_dashboards;
proxy_pass https://<os_domain_url>/_dashboards;
# Update cookie domain and path
# proxy_cookie_domain vpc-workshop-domain-vpc-sanhsxgdhgmlm3ipovjzmbivse.us-east-1.es.amazonaws.com $host;
proxy_cookie_domain <os_domain_url> $host;
proxy_set_header Accept-Encoding "";
sub_filter_types *;
sub_filter DOMAIN_ENDPOINT $host;
sub_filter_once off;
# Response buffer settings
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
location ~ \/(log|sign|fav|forgot|change|saml|oauth2) {
# Handle redirects to Dashboards
# proxy_redirect https://vpc-workshop-domain-vpc-sanhsxgdhgmlm3ipovjzmbivse.us-east-1.es.amazonaws.com https://$host;
proxy_redirect https://<os_domain_url> https://$host;
}
}
- Use this command to restart NGINX.
$ sudo systemctl restart nginx.service
Testing:
Locate to the url:
https://<public-ip-of-reverse-proxy-instance>/_dashboards
You can now login and go to OpenSearch dashboard
Note:
AWS OpenSearch: tại Access policy, phần Domain access policy, Nếu sử dụng “Do not set domain level access policy” mà không thiết định JSON policy cho phần access control thì sẽ gặp lỗi
"{"Message":"User: anonymous is not authorized to perform: es:ESHttpGet"}"
khi truy cập OpenSearch Dashboards URL thông qua reverse proxy → Chọn ● Only use fine-grained access control
Reference: https://aws.amazon.com/premiumsupport/knowledge-center/opensearch-outside-vpc-nginx/
SG cho con NAT + reverse proxy:
You have to allow HTTP, HTTPS, SSH and PostgreSQL, Custom TCP port 6379 inbound traffic. Also, you have to allow HTTP and HTTPS traffic from your private subnets’ CIDR block.
Configure NAT Instance
sysctl -w net.ipv4.ip_forward=1
yum install iptables-services -y
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
service iptables save
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
systemctl start iptables
chkconfig iptables on