xor

二兎を得るか、一兎をも得ざるか

CentOS 8 のインストールからHTTP/2でWebサーバー立ち上げまで【さくらのVPS】

久々にサーバを立ち上げるにあたって、CentOS 8 をまだ使ったことがなかったので試してみたメモです。

これまでのCentOSとの違いについて

xn--o9j8h1c9hb5756dt0ua226amc1a.com

dev.classmethod.jp

PHPのデフォルトが7系、Pythonのデフォルトが3系になったとのこと。(やったぜ)
AppStreamというreposができている。
yum ではなく dnf になっている(エイリアスはある)。
などなど。

OSインストール

f:id:ukkz:20200810185547p:plain

既存の使っていなかったVPSを引き継いだので、そのまま再インストールから始めます。
パケットフィルタリングは、画像ではSSHとWebになっていますが、「使用しない」設定でよいです。
あとでOS内でファイアウォールを設定します。

しばらく放置して「稼働中」の表示が出ればインストール完了です。

SSH設定

コントロールパネルのコンソールから「シリアルコンソール」を選び、新しく開いたウインドウのCUIからrootでログインします。
VNCコンソールだとデフォルトのキー配列がJISになっているのでUS配列の人は注意です。

まず以下の手順で一般ユーザを作成します。

help.sakura.ad.jp

rootユーザのまま、作成した一般ユーザをsudoersに追加します。
今回は visudo で設定ファイルを見たところ、デフォルトでwheelグループのsudoが許可されていたので編集不要でした。

help.sakura.ad.jp

sshdサービスの設定ファイルを編集します。

# vi /etc/ssh/sshd_config

ここで3点変更します。
特にポートは、必ず32768番以降のエフェメラルポートを使用するように変更しておきます。
22番を使わないだけで、SSHへのアタック(不正ログイン試行)が大幅に減ります。
あとの2点はルートログインとパスワードログインの禁止です。つまり一般ユーザの公開鍵によるログインのみを許可するようにします。

Port 40220      # 一例
PermitRootLogin no
PasswordAuthentication no

:wq で書き込んだあと、sshdサービスを再起動します。

# service sshd restart
Redirecting to /bin/systemctl restart sshd.service

そのあと一旦ログアウトし、作成したユーザでログインします。まだこの時点ではWebのシリアルコンソールからです。

$ cd
$ mkdir .ssh
$ vi .ssh/authorized_keys

f:id:ukkz:20200810192608p:plain

あらかじめ自分のローカルPCで作っておいた公開鍵をコピペで貼り付けて保存します。

$ chmod 700 .ssh
$ chmod 600 .ssh/authorized_keys
$ ls -al .ssh
total 12
drwx------ 2 user user 4096 Aug 10 19:22 .
drwx------ 3 user user 4096 Aug 10 19:29 ..
-rw------- 1 user user  401 Aug 10 19:22 authorized_keys

パーミッションを、.sshは700、authorized_keysは600にしておきます。

次にローカルPCのターミナルからSSHコマンドを打ち、疎通を確認します。

f:id:ukkz:20200810200740p:plain

ブラウザのシリアルコンソールはまだ開いたままにしておきます。

ファイアウォール

デフォルトでファイアウォールが入っていますが、念のため確認します。

$ sudo firewall-cmd --list-all
FirewallD is not running

ここでfirewalldを起動してしまうと容赦無くSSHが切られてしまうので、またWebのシリアルコンソールに戻って操作します。

# cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services
# vi /etc/firewalld/services/ssh.xml

SSHサービスを通すテンプレートファイルをコピーし、内部のポート番号を自身で決めた値に変更します。

f:id:ukkz:20200810235946p:plain

完了したらfirewalldを起動し、SSHサービスを登録します。

# service firewalld start
Redirecting to /bin/systemctl start firewalld.service
# firewall-cmd --add-service=ssh --permanent
success
# firewall-cmd --reload
success

この状態でローカルのターミナルからSSHが切断されずにつながっていれば大丈夫です。

このままついでに、httpとhttpsを通すようにして、サービスも自動起動に設定しておきます。

# firewall-cmd --add-service=http --permanent
success
# firewall-cmd --add-service=https --permanent
success
# firewall-cmd --reload
success

# systemctl enable firewalld
Created symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service → /usr/lib/systemd/system/firewalld.service.
Created symlink /etc/systemd/system/multi-user.target.wants/firewalld.service → /usr/lib/systemd/system/firewalld.service.

設定確認として、以下のようになっていれば問題ありません。

# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources:
  services: cockpit dhcpv6-client http https ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

ここまでできればブラウザ側は全部閉じてしまって大丈夫です。

シェルとエディタの設定

※ここは壮絶な宗派争いがあるのであくまで個人の設定です

zsh + oh-my-zsh

$ sudo dnf install zsh
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
$ which zsh
/usr/bin/zsh
$ sudo vi /etc/passwd # ログインシェルを/usr/bin/zshに変更

再ログインしてzshになってればOKです。

vim

$ sudo dnf install vim

HTTPサーバとSSL接続

nginx

sig9.hatenablog.com

AppStreamとやらを無効にし、nginx公式リポジトリからインストールします。
/etc/yum.repos.d/nginx.repo を以下の通り作成します。

[nginx-stable]
name=nginx official (stable) repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key

リポジトリ確認するとこんな感じです。

$ dnf info nginx
Available Packages
Name         : nginx
Epoch        : 1
Version      : 1.14.1
Release      : 9.module_el8.0.0+184+e34fea82
Architecture : x86_64
Size         : 570 k
Source       : nginx-1.14.1-9.module_el8.0.0+184+e34fea82.src.rpm
Repository   : AppStream
Summary      : A high performance web server and reverse proxy server
URL          : http://nginx.org/
License      : BSD
Description  : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and
             : IMAP protocols, with a strong focus on high concurrency, performance and low
             : memory usage.

$ dnf --disablerepo=AppStream info nginx
Available Packages
Name         : nginx
Epoch        : 1
Version      : 1.19.1
Release      : 1.el8.ngx
Architecture : x86_64
Size         : 814 k
Source       : nginx-1.19.1-1.el8.ngx.src.rpm
Repository   : nginx-stable
Summary      : High performance web server
URL          : http://nginx.org/
License      : 2-clause BSD-like license
Description  : nginx [engine x] is an HTTP and reverse proxy server, as well as
             : a mail proxy server.

公式からインストールします。

$ sudo dnf --disablerepo=AppStream install nginx

立ち上げ前にある程度設定しときます。

/etc/nginx/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/all.error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections 1024;
    multi_accept        on;
    use epoll;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    server_tokens   off;
    charset         utf-8;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  json  '{"remoteAddr": "$remote_addr", "datetime": "$time_iso8601", "requestPath": "$request_uri", '
                      '"httpProtocol": "$server_protocol", "httpMethod": "$request_method", "httpStatusCode": $status, '
                      '"responceSize": $body_bytes_sent, "referrer": "$http_referer", "userAgent": "$http_user_agent", '
                      '"XForwardedFor": "$http_x_forwarded_for", "hostname": "$host", "scheme": "$scheme"}';

    access_log  /var/log/nginx/all.access.log  main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    #gzip            on;
    keepalive_timeout  65;


    include /etc/nginx/conf.d/*.conf;
    client_max_body_size 8M;
}

ホームディレクトリを作成し、テスト用のHTMLを置いておきます。

$ sudo mkdir /var/web
$ sudo mkdir /var/web/main
$ sudo chown -R myname:nginx /var/web/main
$ echo '<html><head><title>okay</title></head><body><h1>It maybe works!</h1></body></html>' > /var/web/main/index.html

/etc/nginx/conf.d/default.conf : 一部のみ書き換えます。

listen       80 default_server;
location / {
    root   /var/web/main;
    index  index.html index.htm;
}

設定ファイルが間違っていないことを確認したら、サービスとして立ち上げ、VPSIPアドレスにアクセスしてページが表示されるか確認します。

$sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo service nginx start
Redirecting to /bin/systemctl start nginx.service
$ sudo systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

f:id:ukkz:20200811034937p:plain

ヨシ!

無料ドメイン取得とSSL

freenom

ドメインはみんな大好きfreenomさんで。いつもお世話になってます。

Freenom - A Name for Everyone

f:id:ukkz:20200814123348p:plain

適当なドメインを取得したら、自分のドメインリストから新規取得できたドメインのページに行き、DNS管理のタブを開きます。
画像のように、"Target" のところにだけVPSIPアドレスを入れ、変更を保存します。

nginxの設定ファイル /etc/nginx/conf.d/default.conf に取得したドメインを追加しておき、このドメインで先ほどのサンプルページにアクセスできるか試しておきます。
この設定ファイルは、更新するたびに必ず nginx -t による書式チェックと nginx -s reload による再読み込みを忘れないようにしましょう。

server {
    listen       80 default_server;
    server_name  new-domain.tk;
}

Let's Encrypt

VPSへのSSHに戻り、EPELリポジトリを追加してからcertbotをインストールします。

$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
$ sudo dnf install certbot python3-certbot-nginx

インストール完了したらただ実行するだけです。
実行オプションをつけずとも、nginxプラグインが自動で有効になってくれます。
あとは対話形式で簡単に設定できます。ありがたや。

$ sudo certbot
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): test@mail.com ←自分のメールアドレスを入力

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A ←承諾する(A)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y ←EFFからのお知らせメール受け取るかどうか、Nでも問題ないはず

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: new-domain.tk
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1 ←初めてなら1番に取得したドメインが表示されてるので1を入力
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for new-domain.tk
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/conf.d/default.conf
Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/default.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://new-domain.tk
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Subscribe to the EFF mailing list (email: test@mail.com).

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/new-domain.tk/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/new-domain.tk/privkey.pem
   Your cert will expire on 2020-11-12. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

最後にもう一度、 /etc/nginx/conf.d/default.conf を編集し、certbotによって新しく付け加えられたオプションのうち、 listen の行の末端に "http2" の文言を入れ、保存&書式チェック&nginx再起動を行います。

    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/new-domain.tk/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/new-domain.tk/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

以上!お疲れ様でした。