LPIC201/202 あずき本 ch10 Webサーバとプロキシサーバ (3/3)

LPIC202nginxsquid勉強メモ資格勉強

出典: 

10.3 プロキシサーバの設定

利点

  • アクセスコントロール

    • 【補】実務で外部IFコールを特定のプロキシ経由に制限したことがあった(2019)
  • キャッシュ

10.3.1 Squidの基本設定

インストール

sudo yum -y install squid
sudo systemctl start squid

設定ファイル

sudo cat /etc/squid/squid.conf
#
# Recommended minimum configuration:
#

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8	# RFC1918 possible internal network
acl localnet src 172.16.0.0/12	# RFC1918 possible internal network
acl localnet src 192.168.0.0/16	# RFC1918 possible internal network
acl localnet src fc00::/7       # RFC 4193 local private network range
acl localnet src fe80::/10      # RFC 4291 link-local (directly plugged) machines

acl SSL_ports port 443
acl Safe_ports port 80		# http
acl Safe_ports port 21		# ftp
acl Safe_ports port 443		# https
acl Safe_ports port 70		# gopher
acl Safe_ports port 210		# wais
acl Safe_ports port 1025-65535	# unregistered ports
acl Safe_ports port 280		# http-mgmt
acl Safe_ports port 488		# gss-http
acl Safe_ports port 591		# filemaker
acl Safe_ports port 777		# multiling http
acl CONNECT method CONNECT

#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#

# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost

# And finally deny all other access to this proxy
http_access deny all

# Squid normally listens to port 3128
http_port 3128

# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /var/spool/squid 100 16 256

# Leave coredumps in the first cache dir
coredump_dir /var/spool/squid

#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp:		1440	20%	10080
refresh_pattern ^gopher:	1440	0%	1440
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
refresh_pattern .		0	20%	4320

10.3.2 アクセス制御の設定

抜粋

#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports

# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports

# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager

# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost

#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#

# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost

# And finally deny all other access to this proxy
http_access deny all

www1.example.com宛の通信を拒否してみる

--- /etc/squid/squid.conf.default	2020-11-16 16:45:17.000000000 +0000
+++ /etc/squid/squid.conf	2021-01-01 14:22:00.021488439 +0000
@@ -45,6 +45,8 @@
 #
 # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
 #
+acl badhosts dstdomain www1.example.com
+http_access deny badhost
 
 # Example rule allowing access from your local networks.
 # Adapt localnet in the ACL section to list your (internal) IP networks

構文チェック

sudo squid -k parse ; echo $?
...
2021/01/01 14:22:09| ACL not found: badhost
FATAL: Bungled /etc/squid/squid.conf line 49: http_access deny badhost
Squid Cache (Version 3.5.20): Terminated abnormally.
CPU Usage: 0.012 seconds = 0.005 user + 0.007 sys
Maximum Resident Size: 26656 KB
Page faults with physical i/o: 0
1

ACL名の間違いを検出してくれる

修正

--- /etc/squid/squid.conf.default	2020-11-16 16:45:17.000000000 +0000
+++ /etc/squid/squid.conf	2021-01-01 14:24:59.089164229 +0000
@@ -45,6 +45,8 @@
 #
 # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
 #
+acl badhosts dstdomain www1.example.com
+http_access deny badhosts
 
 # Example rule allowing access from your local networks.
 # Adapt localnet in the ACL section to list your (internal) IP networks
sudo squid -k parse ; echo $?
...
2021/01/01 14:25:25| Initializing https proxy context
0

OK

設定はまだ反映されない

curl --proxy http://localhost:3128 http://www1.example.com/
www1

HUPシグナル送信すると設定反映

sudo systemctl reload squid

curl --proxy http://localhost:3128 http://www1.example.com/
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta type="copyright" content="Copyright (C) 1996-2016 The Squid Software Foundation and contributors">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>ERROR: The requested URL could not be retrieved</title>
...

アクセスが拒否された。OK

10.4 Nginxとリバースプロキシ

リバースプロキシ、メールプロキシ機能も有するWebサーバ

10.4.1 Nginxの設定

sudo yum -y install nginx

Apache HTTP Serverと80番ポートが競合するので一旦止める

sudo systemctl stop httpd
sudo systemctl start nginx

Nginxは1つのマスタープロセスと複数のワーカープロセスからなる

ps auxw | grep nginx
root     25582  0.0  0.1 105500  1980 ?        Ss   14:36   0:00 nginx: master process /usr/sbin/nginx
nginx    25583  0.0  0.2 105968  2920 ?        S    14:36   0:00 nginx: worker process
nginx    25584  0.0  0.2 105968  2920 ?        S    14:36   0:00 nginx: worker process
wand     25598  0.0  0.0 112780   684 pts/1    S+   14:38   0:00 grep --color=auto nginx
  • マスタープロセスはrootで動作
  • ワーカープロセスはnginx一般ユーザで2つ動作

設定確認

sudo cat /etc/nginx/nginx.conf
# 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 2048;

    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 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        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 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        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 HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#        location = /404.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#        location = /50x.html {
#        }
#    }

}

抜粋

user nginx;
worker_processes auto;

worker_processes auto: CPUコア数に基づいてワーカープロセス数決定

cat /proc/cpuinfo | grep processor
processor	: 0
processor	: 1

Apache HTTP Server同様、設定ファイルは分割管理することもできる

ls /etc/nginx/
conf.d			koi-utf		    scgi_params
default.d		koi-win		    scgi_params.default
fastcgi.conf		mime.types	    uwsgi_params
fastcgi.conf.default	mime.types.default  uwsgi_params.default
fastcgi_params		nginx.conf	    win-utf
fastcgi_params.default	nginx.conf.default

が、CentOS7でyum installでインストールしたNginxは分割用ディレクトリだけ用意され、設定ファイルは分割されていなかった

ls /etc/nginx/*.d
/etc/nginx/conf.d:

/etc/nginx/default.d:

モジュールとコンテキスト

NginxはApache HTTP Server同様モジュール構造

nginx -Vで使用しているモジュール確認可能

nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.1.1c FIPS  28 May 2019 (running with OpenSSL 1.1.1g FIPS  21 Apr 2020)
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'

httpd -lhttpd -M のような気の利いた機能はないので自分で整形する

nginx -V 2>&1 | tr - '\n' | grep _module
http_ssl_module 
http_v2_module 
http_realip_module 
stream_ssl_preread_module 
http_addition_module 
http_xslt_module=dynamic 
http_image_filter_module=dynamic 
http_sub_module 
http_dav_module 
http_flv_module 
http_mp4_module 
http_gunzip_module 
http_gzip_static_module 
http_random_index_module 
http_secure_link_module 
http_degradation_module 
http_slice_module 
http_stub_status_module 
http_perl_module=dynamic 
http_auth_request_module 
mail_ssl_module 
stream_ssl_module 
google_perftools_module 

設定のディレクティブはモジュールごとに決まったコンテキスト内に記述する

coreモジュールのmainコンテキスト:

# 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モジュールのeventsコンテキスト:

events {
    worker_connections 1024;
}

httpモジュールのhttpコンテキスト:

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 2048;

    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コンテキスト

http {
...
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

さらに入れ子のlocationコンテキスト

http {
...
    server {
...
        location / {
        }
    }

親ブロック({})の設定内容は子ブロックにも引き継がれ、子で上書きすることもできる

  • 例えばkeepalive_timeoutなどはhttpで全体のものを設定し、serverごと、locationごとに上書き可能

10.4.2 リバースプロキシの設定

httpdを8080番ポートで動かす

--- /etc/httpd/conf/httpd.conf.bak	2021-01-01 15:03:41.000560351 +0000
+++ /etc/httpd/conf/httpd.conf	2021-01-01 15:05:37.656166674 +0000
@@ -39,9 +39,9 @@
 # prevent Apache from glomming onto all bound IP addresses.
 #
 #Listen 12.34.56.78:80
-Listen 127.0.0.1:80
-Listen 192.168.1.1:80
-Listen 192.168.1.2:80
+Listen 127.0.0.1:8080
+Listen 192.168.1.1:8080
+Listen 192.168.1.2:8080
 
 <VirtualHost 192.168.1.1:80>
   Servername www1.example.com
apachectl configtest
sudo apachectl start

curl localhost:8080
index.html dayo

80番で動いているNginxにリバースプロキシの設定を行う

ひとまず最小設定

--- /etc/nginx/nginx.conf.bak	2021-01-01 15:10:05.786649647 +0000
+++ /etc/nginx/nginx.conf	2021-01-01 15:12:11.075818906 +0000
@@ -45,6 +45,7 @@
         include /etc/nginx/default.d/*.conf;
 
         location / {
+            proxy_pass http://localhost:8080
         }
 
         error_page 404 /404.html;

コンフィグチェック: nginx -t

sudo nginx -t
nginx: [emerg] unexpected "}" in /etc/nginx/nginx.conf:49
nginx: configuration file /etc/nginx/nginx.conf test failed

行末の;を忘れていた

--- /etc/nginx/nginx.conf.bak	2021-01-01 15:10:05.786649647 +0000
+++ /etc/nginx/nginx.conf	2021-01-01 15:13:05.914394558 +0000
@@ -45,6 +45,7 @@
         include /etc/nginx/default.d/*.conf;
 
         location / {
+            proxy_pass http://localhost:8080;
         }
 
         error_page 404 /404.html;
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

なお、管理者権限で実行しないとソケットのPermission deniedでエラーになる

nginx -t
nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
2021/01/01 15:13:46 [warn] 25930#0: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:5
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
2021/01/01 15:13:46 [emerg] 25930#0: open() "/run/nginx.pid" failed (13: Permission denied)
nginx: configuration file /etc/nginx/nginx.conf test failed

設定反映

sudo systemctl reload nginx

curl -v localhost > /dev/null

502が返ってきている…

< HTTP/1.1 502 Bad Gateway

エラーログ

sudo tail -n 2 /var/log/nginx/error.log
2021/01/01 15:28:27 [crit] 26253#0: *22 connect() to [::1]:8080 failed (13: Permission denied) while connecting to upstream, client: ::1, server: _, request: "GET / HTTP/1.1", upstream: "http://[::1]:8080/", host: "localhost"
2021/01/01 15:28:27 [crit] 26253#0: *22 connect() to 127.0.0.1:8080 failed (13: Permission denied) while connecting to upstream, client: ::1, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "localhost"

upstreamのhttp://[::1]:8080/http://127.0.0.1:8080/にはリバースプロキシできているがPermission denied

どうやらSELinuxが効いているとローカルホスト内でのリバースプロキシはPermission deniedとなるらしい

getenforce
Enforcing
sudo setenforce permissive

curl localhost
index.html dayo

OK

最後にSELinuxを戻しておく

sudo setenforce enforcing

ほか、キャッシュの設定や本来のアクセス元の設定も行える

  • キャッシュの設定

    • proxy_cache_path
    • proxy_temp_path
    • proxy_cache_key
  • HTTPヘッダの設定

    • proxy_set_header HOST $host
    • proxy_set_header X-Real-IP $remote_addr
    • proxy_set_header X-Forwarded-Host $host
    • proxy_set_header X-Forwarded-Server $host
    • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for