マイIPは遅い

先日、インターリンク社のマイIPサービスを使って固定IPアドレスを割り当てたわけだけど、はっきり言って通信速度が遅い。どのくらい遅いか、マイIPを使わない場合と比べてみた。

  • マイIPなし: 770Mbps,アップロード 560Mbps
  • マイIPあり: 5.9Mbps、 アップドード 5.6Mbps

通信速度は fast.com ってページで測った。マイIP経由だと約1/100だ。何度か測ってみたけどだいたいこのオーダー。これじゃせっかくの NURO光回線(下り2Gbps,上り1Gbps)がもったいない。

そりゃもちろん、VPN を介してインターリンク社のネットワークを経由するんだから、その分遅くなるのは承知してたけど、これほどとは。これは何かほかの方法を考えるかなぁ。

[追記]

インターリンクの FAQ に通信速度について書いてあった。曰く:

実際の通信速度は弊社のマイIPサーバーとお客様のPCとの間の接続環境によって変化します。
弊社ではおよそ 2Mbps~4Mbpsと推測しております。

マイIPサービスの通信速度はどれくらいですか? – インターリンク FAQ

だいたい実測通りだ。さきに言ってよ……(いや、見つけられなかったオレが悪いんだけどさ)。

カテゴリー: Misc | コメントする

インターリンクのマイIPサービスでCentOS8マシンに固定IPアドレスを割り当てる

インターリンクのマイIPサービス

NURO光は固定IPアドレスを割り当てるサービスを提供していないので、インターリンク社のマイIPというサービスを使って固定IPアドレスを割り当てる。

 cf. INTERLINK

上のページから、マイIPサービスに申し込んだ。申し込み自体は何も難しくはない。クレジット払いにしたのですぐに利用できるようになる。

問題はここから。マイIPサービスは、VPN を使って PC とインターリンクのサーバを繋ぎ、PC の ppp0 インターフェイスに固定IPアドレスを割り当てるようになっている(ようだ)。そのためには PPTP クライアントの設定が必要なんだけど、これでハマった。

環境

まずは環境を整理しておこう。

  • OS: CentOS 8.0
  • マイIPに必要な情報は取得済み

設定作業(1)

インターリンクの公開しているマニュアルに沿って作業する。

 cf. https://faq.interlink.or.jp/faq2/View/wcDisplayContent.aspx?id=501

マイIP接続ツールをダウンロードして /etc 以下に展開。

[[email protected] ~]$ curl -O https://www.interlink.or.jp/support/vpn/myip/myiptools/myiptools.tar.gz
[[email protected] ~]$ sudo tar xvzf myiptools.tar.gz -C /etc

設定ファイル /etc/myip/myip.conf を自分の接続情報に合わせて編集。

[[email protected] ~]$ sudo vim /etc/myip/myip.conf

初期設定スクリプトを実行。

[[email protected] ~]$ sudo /etc/myip/myip-setup

ここでエラーが起きた。メッセージを抜粋する。

一致した引数がありません: pptp-setup
エラー: 一致するものが見つかりません
/etc/myip/myip-setup: 行 111: pptpsetup: コマンドが見つかりません
/etc/myip/myip-setup: 行 117: /etc/ppp/peers/myip_miXXXXXX: そのようなファイルやディレクトリはありません

myip_miXXXXXX っていうファイルは自分用の設定ファイル(実際には miXXXXXX の部分に自分のログインIDが入る)。

初期設定スクリプト myip-setup の中を覗いてみて分かったのは、pptp-setup っていうパッケージをインストールしようとしているけどそれが失敗しているということと、そのせいか pptpsetup コマンドが見つからないようだ、ってことだ。

じゃあ、手動で pptp-setup パッケージをインストールしてやればいいかというと、そんなパッケージは無いらしい。

[[email protected] ~]$ dnf search pptp-setup
一致する項目はありませんでした。

というところまでが昨日の話。

設定作業(2)

今日になっていろいろググってみたところ、PPTP Client の公式サイトを見つけた。

 cf. http://pptpclient.sourceforge.net/

このページの Download セクションには、pptp には pptpsetup が含まれている、と書いてある。

pptp, the helper program used by pppd to make a tunnel, which also includes pptpsetup,

なら、ここからダウンロードして pptpsetup をコピーしてやったらいいんじゃないか。というわけで早速ダウンローとして展開。するとたしかに含まれていた。

[[email protected] ~]$ wget https://sourceforge.net/projects/pptpclient/files/pptp/pptp-1.10.0/pptp-1.10.0.tar.gz
[[email protected] ~]$ tar xzvf pptp-1.10.0.tar.gz
[[email protected] ~]$ ls pptp-1.10.0
AUTHORS            dirutil.c        pptp_compat.h   routing.c
COPYING            dirutil.h        pptp_ctrl.c     routing.h
ChangeLog          options.pptp     pptp_ctrl.h     test-redirections.c
DEVELOPERS         orckit_quirks.c  pptp_gre.c      test-redirections.h
Documentation      orckit_quirks.h  pptp_gre.h      util.c
INSTALL            ppp_fcs.c        pptp_msg.h      util.h
Makefile           ppp_fcs.h        pptp_options.h  vector.c
NEWS               pptp.8           pptp_quirks.c   vector.h
PROTOCOL-SECURITY  pptp.c           pptp_quirks.h   vector_test.c
README             pptp_callmgr.c   pptpsetup       version.c
TODO               pptp_callmgr.h   pqueue.c        version.h
USING              pptp_compat.c    pqueue.h

この pptpsetup、中を覗いてみると Perl のスクリプトのようだ。/usr/sbin にコピーして実行権限をつけてやる。

[[email protected] ~]$ sudo cp pptp-1.10.0/pptpsetup /usr/sbin
[[email protected] ~]$ sudo chmod 755 /usr/sbin/pptpsetup

さあ、これでどうだろう。初期設定スクリプトを実行。

[[email protected] ~]$ sudo /etc/myip/myip-setup
CentOS-8 - AppStream                            2.0 kB/s | 4.3 kB     00:02    
CentOS-8 - Base                                 3.2 kB/s | 3.9 kB     00:01    
CentOS-8 - Extras                               673  B/s | 1.5 kB     00:02    
Package gawk-4.2.1-1.el8.x86_64 is already installed.
Package sed-4.5-1.el8.x86_64 is already installed.
依存関係が解決しました。
行うべきことはありません。
完了しました!
/sbin/pptpsetup: can't write to '/etc/ppp/peers/myip_miXXXXXX': No such file or directory
/etc/myip/myip-setup: 行 117: /etc/ppp/peers/myip_miXXXXXX: そのようなファイルやディレクトリはありません
done.

pptpsetup コマンドは実行できたようだけど、ファイルが書き込めないといっている。調べてみると /etc/ppp/peers ディレクトリが無いようなので作ってやる。

[[email protected] ~]$ sudo mkdir /etc/ppp/peers

こんどはどうだ。

[[email protected] ~]$ sudo /etc/myip/myip-setup
メタデータの期限切れの最終確認: 0:01:04 時間前の 2019年12月15日 10時20分25秒 に実施しました。
Package gawk-4.2.1-1.el8.x86_64 is already installed.
Package sed-4.5-1.el8.x86_64 is already installed.
依存関係が解決しました。
行うべきことはありません。
完了しました!
done.

エラーなし。うまくいったようだ。これでやっと次にすすめる。

設定作業(3)

マニュアルによると:

PPTP接続に必要なTCPポート1723およびGREプロトコルを通過できるようにしておく必要があります。

と書いてあるけど、やり方が書いてない。ポートの開け方はわかる。

[[email protected] ~]$ sudo firewall-cmd --zone=public --add-port=1723/tcp --permanent

GREプロトコルの方はググったら↓のページを見つけた。

 cf. https://www.vultr.com/docs/how-to-establish-a-gre-tunnel-between-two-centos-7-servers
 cf. https://github.com/firewalld/firewalld/issues/30

ip_gre モジュールをロードする。

[[email protected] ~]$ modprobe ip_gre

GRE プロトコルを通過させるのは firewall-cmd でできるようだ。

[[email protected] ~]$ sudo firewall-cmd --zone=public --add-rich-rule='rule protocol value="47" accept' --permanent

さあ、これで準備は整ったはずだ。

接続開始

myip-up コマンドで接続を開始する。

[[email protected] ~]$ sudo /etc/myip/myip-up
Using interface ppp0
Connect: ppp0 <--> /dev/pts/1
CHAP authentication succeeded
MPPE 128-bit stateless compression enabled
local  IP address 202.241.129.128
remote IP address 202.241.128.1
private IP mode.
done.

ifconfig コマンドの出力(下はその抜粋)をみると、ppp0 インターフェイスに固定IPアドレスが割り振られているのがわかる。

ppp0: flags=4305  mtu 1346
        inet 202.241.129.128  netmask 255.255.255.255  destination 202.241.128.1
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 7  bytes 100 (100.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 134 (134.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ちなみに、接続を終了するには /etc/myip/myip-down コマンドを実行する。

確認

別のネットワークに繋がってる Windows マシンから、http://202.241.129.128/hello.html にアクセスしたところ、ちゃんと「Hello, this is rollo.」と表示されるのを確認した(rollo ってのは VPN 接続したホストの名前)。

これにて無事完了。

[追記 12/16]

一昨日(12/14)、スクリプトがエラーになって先に進めなくなったところで、インターリンク社に問い合わせをしたんだけど、今日になってその回答が来た。曰く:

大変申し訳ございませんが、マイIPはCentOS 8.0に対応しておりません。

……まぁ、予想はしてたけどね。リリースされたばっかりのディストリビューションだしね。

それに、パッケージが無かったりすりのはディストリビューションの方の問題であって、インターリンク社が悪いわけではない。

ともかく、CentOS 8.0 でマイIPサービスを使おうという人がいたら、上に書いた方法でうまくいったということを参考にしてもらおう。

カテゴリー: CentOS, Misc | コメントする

NURO光が開通した

昨日のことなんだけど、時間がとれなかったので今日書く。

回線の工事をやってもらって、NURO光が開通した。工事は宅内工事と屋外工事が必要なんだけど、1日でやってもらった(追加工事費がかかる)。宅内工事は午前中に、屋外工事は午後4時ころには終わった。

で、設置された ONU というルータみたいな機器に、apostrophe と rollo の2台を有線で繋いで試してみた。結果、2台のコンピュータ同士も通信できるし、もちろんインターネットにも接続できる。まずは大丈夫のようだ。この記事もNURO光で接続して書いてる。

ネットワークアドレスを変更

デフォルトではネットワークアドレスが 192.168.1.0/24 になってるんだけど、これでは既存のネットワークとかぶるので、192.168.2.0/24 に変更する。

ONU は web 画面で設定できるようになっているので、http://192.168.1.1 にブラウザでアクセスしてログイン。ONU 自身のアドレスを始め、DHCP で割り当てるアドレスの範囲、デフォルトゲートウェイなどを 192.168.2.0/24 になるように変更した。これで電源を入れなおせばひとまずは完了。

あとは、web サーバをインターネットに公開するために、固定IPアドレスの設定なんかをやってたんだけどなかなかうまくいかずに昨日は時間切れ。というわけで今日書いてる次第。これについては記事を分ける。

カテゴリー: Misc | コメントする

Samba がこわれた

ローカルネットワーク上に作った Samba サーバがこわれた。先週の土曜日の話で、細かいことは覚えてないのでおおまかに書く。

最初に書いておくと、この Samba サーバは、ホスト名を wplj といい、OS は Ubuntu 16.04。

事の発端は Samba サーバにユーザを限定した共有フォルダを作ろうとしたことだ。下のページあたりを参考に /etc/samba/smb.conf ファイルに追記して samba サービスをリスタートしたところ、エラーになった。

 cf. アクセス権付の共有フォルダ作成 – Server World

追記した部分を削除してリスタートしてもエラーになる。仕方がないので Samba 自体をいったん削除してインストールしなおしても同じだった。再インストール後は最低限の設定だけで、共有フォルダを作らなくてもエラーになるんだから訳がわからない。設定自体は、さっきまで動いていた設定ファイル(バックアップしておいた)からコピペしたんだから間違ってないはずだ。どういうわけさ。

Samba サーバは Windows マシンのデータバックアップ用で、データ自体は残っているので大丈夫といえば大丈夫なんだけど、Windows からアクセスできなくなったのは不便だ。どうしようか。

[追記]

とりあえず、データバックアップ用サーバの nightschool にデータを移動して、Samba サーバを立てた。nightschool は CentOS 7.7 だけど、すんなりといった。何が違うんだ。

とにかく、データに Windows からもアクセスできるようにはなったので良しとする。上に書いたように Samba は Windows マシンのデータバックアップ用途だったので、そういう意味では nightschool にまとまってよかったのかも。

ユーザを限定した共有フォルダを作る件についてはまた今度。

カテゴリー: Misc, Ubuntu | コメントする

Ubuntu 16.04 に Dropbox をインストール

メインマシンの apostrophe (OS は Ubuntu 16.04 LTS)に Dropbox をインストールする。

まずはこのページから .deb ファイルをダウンロード。で、インストールする。.deb ファイルのインストールは dpkg コマンド。apt じゃないんだな。

[email protected] $ cd Downloads
[email protected] $ ls
dropbox_2019.02.14_amd64.deb
[email protected] $ sudo dpkg -i dropbox_2019.02.14_amd64.deb
[sudo] takatoh のパスワード: 
以前に未選択のパッケージ dropbox を選択しています。
(データベースを読み込んでいます … 現在 239399 個のファイルとディレクトリがインストールされています。)
dropbox_2019.02.14_amd64.deb を展開する準備をしています …
dropbox (2019.02.14) を展開しています…
dpkg: 依存関係の問題により dropbox の設定ができません:
 dropbox は以下に依存 (depends) します: libpango1.0-0 (>= 1.36.3) …しかし:
  パッケージ libpango1.0-0 はまだインストールされていません。

dpkg: パッケージ dropbox の処理中にエラーが発生しました (--install):
 依存関係の問題 - 設定を見送ります
man-db (2.7.5-1) のトリガを処理しています …
desktop-file-utils (0.22-1ubuntu5.2) のトリガを処理しています …
bamfdaemon (0.5.3~bzr0+16.04.20180209-0ubuntu1) のトリガを処理しています …
Rebuilding /usr/share/applications/bamf-2.index…
gnome-menus (3.13.3-6ubuntu3.1) のトリガを処理しています …
mime-support (3.59ubuntu1) のトリガを処理しています …
hicolor-icon-theme (0.15-0ubuntu1.1) のトリガを処理しています …
処理中にエラーが発生しました:
 dropbox

あれ、エラーが発生した。libpango1.0-0 っていうパッケージがインストールされてないみたいだ。インストールする。こんどは apt で。

[email protected] $ sudo apt install libpango1.0-0

もういちど Dropbox のインストール。

[email protected] $ sudo dpkg -i dropbox_2019.02.14_amd64.deb
(データベースを読み込んでいます … 現在 239431 個のファイルとディレクトリがインストールされています。)
dropbox_2019.02.14_amd64.deb を展開する準備をしています …
dropbox (2019.02.14) で (2019.02.14 に) 上書き展開しています …
dropbox (2019.02.14) を設定しています …
Please restart all running instances of Nautilus, or you will experience problems. i.e. nautilus --quit
Dropbox installation successfully completed! You can start Dropbox from your applications menu.
man-db (2.7.5-1) のトリガを処理しています …
desktop-file-utils (0.22-1ubuntu5.2) のトリガを処理しています …
bamfdaemon (0.5.3~bzr0+16.04.20180209-0ubuntu1) のトリガを処理しています …
Rebuilding /usr/share/applications/bamf-2.index…
gnome-menus (3.13.3-6ubuntu3.1) のトリガを処理しています …
mime-support (3.59ubuntu1) のトリガを処理しています …
hicolor-icon-theme (0.15-0ubuntu1.1) のトリガを処理しています …

こんどは大丈夫のようだ。しばらく待つと、Dropbox のウィンドウが立ち上がるので、指示に従って Dropbox をスタート。あとはアカウントの設定をすれば、ファイルの同期が始まる。

カテゴリー: Misc, Ubuntu | コメントする

web サーバからファイルをダウンロードできない問題、その後

前エントリ、というかその追記部分の続き。

MyDNS にログインして、DNS の更新ログを見てみると、最後に IPv4 が更新されたのが24日の17時ころ。その後更新されてない。

いったんはうまくいったのは、24日17時ころに更新した IPv4 アドレスが有効だったからだろう。その後 WiMAX 端末に割り当てられたアドレスが変わったにもかかわらず、DNS が更新されなかったのが原因ではないか。もう少し正確に言うと、IPv6 アドレスだけが更新されて IPv4 アドレスが更新されなかったのが原因なんだと思う。

そこで、試しに MyDNS の設定ページで IPv4 アドレスを 0.0.0.0、IPv6 アドレスを 0:0:0:0:0:0:0:0 に設定しておいて、bigswifty 上でアドレス通知のスクリプトを実行してみた。すると案の定、IPv6 アドレスだけが更新されて、IPv4 アドレスは 0.0.0.0 のままだった。思ったとおりだ。

で、どうすればいいかというと、MyDNS のページにヒントが書いてあった。曰く、IPv4 と IPv6 のデュアルスタックのマシンでは通常の通知先 www.mydns.jp ではうまくいかないことがあるらしく、IPv4 アドレスを更新したい場合は ipv4.mydns.jp に通知しろ、ということのようだ。

なのでアドレス通知スクリプトの中の通知先ホスト名を上記の通り変更して、実行してみた。すると、今度はちゃんと IPv4 アドレスが更新された。ログでも確認できたし、ping も通るようになった。

さあ、これでやっと解決だ……というところまでが昨日の朝の話。

その後、夕方ころに出先からファイルダウンロードを試してみたらちゃんとダウンロードできたので大丈夫だと思っていた。ところが家に返ってきて試してみると、やっぱりエラーページが表示されてダウンロードできない。けれどふと気がついて、借りている VPS に ssh でログインして、そこから(つまり家のローカルネットワークでないところから)試してみると、ちゃんとダウンロードできる。どうも家のネットワークからだとエラーになるみたいだ。どゆこと?

でも、まぁ、外部向けの web サーバなんだから外部から使えればそれでいいか。

カテゴリー: CentOS, Misc | コメントする

CentOS 7: 2つのネットワークに繋ぐ

web サーバにしている PC を2つのネットワークに繋ぐようにしたら問題が発生した。よく理解できてないけど、なんとか解決したので書く。

状況整理

まずは、2つ目のネットワークに繋ぐ前の状況を整理しておく。

ウチには2つのインターネット回線があって、それぞれに web サーバを公開している。1つは光回線で1つ目の web サーバのほか、いくつかある PC は全てこのネットワークに繋がっている。もう1つは去年の12月に導入した WiMAX で、2つ目の web サーバだけが有線で繋がっている(クレードルを介している)。2つのネットワークはウチの中では独立していて繋がっていない。

なので、2つ目の web サーバ――面倒だからホスト名で呼ぼう、bigswifty だ――を操作したい時には直接操作するか、インターネット経由で ssh 接続する必要があった。まぁ、これで用は足りてたんだけど、インターネット経由だとホスト名が長いのが微妙だった。

ついでに先に書いておこう、bigswifty の OS は CentOS 7.6 だ。

今日突然思いついた

ほぼ1年間、上記の状態で使ってたんだけど、今日突然思いついた。bigswifty は有線で WiMAXに繋がってるけど、WiFi もあるじゃないか。WiFi で光回線側のネットワークに繋げば、いつもメインで使ってる apostrophe からインターネットを経由しないで ssh できるようになるはずだ。

というわけで、さっそく bigswifty に直接ログインして、WiFi を有効にし、光回線側のネットワークに繋いだ。これで apostrophe から bigswifty に、インターネットを経由しなくても繋がるようになった。やったぜ!

問題発覚

ところがしばらくして問題が発覚した。bigswifty が web サーバとして機能してないのだ。具体的に言うと、インターネット経由で bigswifty からファイルをダウンロードしようとしても Nginx のエラーページが表示されて、ダウンロードできない。

試しに WiFi を無効にしてみると、ちゃんとファイルをダンロードできるようになった。

よくわからないけど解決編

いろいろググった結果、↓このページを見つけた。

 cf. 複数NICでのデフォルトゲートウェイ設定方法 – maruko2 note

ルータの DHCP 機能にまかせていたルーティングを手動で設定してやればいいようだ。これをスタティックルートというらしい。

じゃ、手順を始めよう。まずはデフォルトゲートウェイを設定する。/etc/sysconfig/network ファイルにつぎのように記述する。

GATEWAY=192.168.100.1

デフォルトゲートウェイは WiMAX 端末だ。つぎに、光回線側のネットワークと通信するための設定を書く。WiFi のインターフェイス名は wlo1 なので、/etc/sysconfig/networs-scripts ディレクトリの下に route-wlo1 というファイルを作って、つぎのようにする。

192.168.1.0/24 via 192.168.1.1

192.168.1.0/24(光回線のネットワークのこと)にアクセスするには 192.168.1.1(光回線側のルータ)を経由しろ、っていうことだと思う。

そして network を再起動。

[[email protected] ~]$ sudo systemctl restart network

これで作業は終わり。

はたして、無事、光回線側からも ssh で繋がるし、インターネットからもファイルをダウンロードできるようになった。

[追記:11/25]

現在11月25日午前4時過ぎ。インターネット経由でファイルをダウンロードしようとしたら、Nginx のエラーページが表示されてダウンロードできなかった。

ごめん、上に書いた方法じゃダメだったみたいだ。いったんはちゃんと繋がった(ホントだよ!)から解決できたものだと思ったんだけど……

ローカルネットワーク(光回線側)から ssh で繋ぐことはできる。ping を試してみるとつぎの通り、応答が返ってくる。

[email protected] $ ping bigswifty
PING bigswifty (192.168.1.13) 56(84) bytes of data.
64 bytes from bigswifty (192.168.1.13): icmp_seq=1 ttl=64 time=27.2 ms
64 bytes from bigswifty (192.168.1.13): icmp_seq=2 ttl=64 time=3.87 ms
64 bytes from bigswifty (192.168.1.13): icmp_seq=3 ttl=64 time=3.96 ms
64 bytes from bigswifty (192.168.1.13): icmp_seq=4 ttl=64 time=5.47 ms
64 bytes from bigswifty (192.168.1.13): icmp_seq=5 ttl=64 time=5.03 ms
64 bytes from bigswifty (192.168.1.13): icmp_seq=6 ttl=64 time=9.35 ms
^C
--- bigswifty ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5007ms
rtt min/avg/max/mdev = 3.875/9.153/27.218/8.282 ms

だけど、インターネット経由だと応答が返ってこない。

[email protected] $ ping lathercraft-storage3.mydns.jp
PING lathercraft-storage3.mydns.jp (49.135.111.90) 56(84) bytes of data.
^C
--- lathercraft-storage3.mydns.jp ping statistics ---
37 packets transmitted, 0 received, 100% packet loss, time 35999ms

lathercraft-storage3.mydns.jp っていうのは、bigswifty をインターネットに公開した時のホスト名だ。DDNS の mydns を使ってる。

ここでちょっと思いついて、lathercraft-storage3.mydns.jp が現在どんなアドレスを使ってるのか確かめてみた。このサイトで確認できる。すると、49.135.102.186 だった。これは lathercraft-storage3.mydns.jp に ping を打った時に応答したアドレスと違う。

てことは、問題は DNS だ。mydns には cron にスクリプトを登録して定期的にアドレスの通知をしてるんだけど、手動でやってみた結果がこれ:

<head>
<title>Free Dynamic DNS (DDNS) for Home Server and VPS etc  | MyDNS.JP</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<LINK href="./site.css" rel=stylesheet type=text/css>

</head>
<BODY BGCOLOR="#FFFFFF"
      TEXT="#304040"
      leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"
>
Login and IP address notify OK.<BR>
login_status = 1.<BR>
<BR>
<DT>MASTERID :</DT><DD>mydns882612</DD>
<DT>REMOTE ADDRESS:</DT><DD>240b:12:1461:6100:c480:657b:ef6b:892d</DD>
<DT>ACCESS DAYTIME:</DT><DD>2019/11/24 19:46:44 UTC</DD>
<DT>SERVER ADDRESS:</DT><DD>2604:180:3:ab6::245c</DD>
<BR>

</body>
</html>

REMOTE ADDRESS が通知したアドレスなんだけど、IPv6 のアドレスになっている。問題はこれかぁ。

さて、どうしよう?

カテゴリー: CentOS | コメントする

Nginx + Unicorn on CentOS 8 with SELinux

前のエントリで web アプリを Unicorn で動かすことに成功したので、今度は Nginx と連携する。

その前に unicorn.conf をちょっと修正して、ポートじゃなくて UNIX ソケットを利用するようにする。

#listen "9000"
listen "/run/lcstorage/unicorn.sock"
worker_processes 2
working_directory "/home/lcstorage/lcstorage"
pid "/home/lcstorage/lcstorage/unicorn.pid"
stdout_path "/home/lcstorage/lcstorage/unicorn.log"
stderr_path "/home/lcstorage/lcstorage/unicorn.log"
preload_app true

そしてソケットファイルを置くディレクトリを作る。

[[email protected] lcstorage]$ sudo mkdir /run/lcstorage
[[email protected] lcstorage]$ sudo chown lcstorage:lcstorage /run/lcstorage

Unicorn の準備はこれで終わり。起動しておく。

[[email protected] lcstorage]$ bundle exec unicorn -c unicorn.conf -E production

さて、つぎは Nginx の設定だ。storage1 というホスト名でアクセスできるよう、/etc/nginx/conf.d の下に storage1.conf という名前で設定ファイルを作る。

upstream lcstorage {
    server unix:/run/lcstorage/unicorn.sock;
    #server 127.0.0.1:9000;
}

server {
    # port
    listen      80;

    # server name
    server_name storage1;

    # document root
    #root        /home/lcstorage/lcstorage;

    # index
    #index       index.php index.html index.htm;

    client_max_body_size    4G;

    # log files
    access_log /var/log/nginx/storage1/access.log main;
    error_log  /var/log/nginx/storage1/error.log  warn;

    keepalive_timeout     60;
    proxy_connect_timeout 60;
    proxy_read_timeout    60;
    proxy_send_timeout    60;

    location / {
        #root       /home/lcstorage/lcstorage;

        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;
        proxy_pass http://lcstorage;
    }
}

ログを書き込むディレクトリを忘れずに作っておく。

これで準備はできたはずだ。Nginx を再起動しよう。

[[email protected] conf.d]$ sudo systemctl restart nginx

で、別マシンから http://storage1/ にアクセスしてみると、結果はこうだった。

502 Bad Gateway

あー、これはあれだ、SELinux のせいだ。試しに SELinux を Permissive モードにしてみる。

[[email protected] ~]$ sudo setenforce 0
[[email protected] ~]$ getenforce
Permissive

この状態でもう一度アクセスしていると、ちゃんと File not found. と表示された。なんどもいうけど、返すファイルがないのでこれが正しい動作だ。

つまり、SELinux をどうにかしてやらないといけないわけだ。だけどググってみると、解決策として出てくるのは SELinux を無効にしろ、っていうのばっかり。ちゃんと使い方を説明しているページはほとんど無い。そんな中で参考になったのが以下のページ。

 cf. 【ゼロから始める】初期設定のみのLinuxサーバーに既存のRailsアプリとWebサーバーを導入する – Takeshi’s Blog

と、そこからリンクされているページ。

 cf. RedmineをCentOS 7上で動かすーUnicornとNginx編 – ソフトウェアエンジニアリング

Nginx のエラーログを調べると:

2019/11/23 11:33:23 [crit] 2526#0: *1 connect() to unix:/run/lcstorage/unicorn.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.1.11, server: storage1, request: "GET / HTTP/1.1", upstream: "http://unix:/run/lcstorage/unicorn.sock:/", host: "storage1"

となっていて、ソケットファイルにアクセスできないようだ。じゃあ、ソケットファイルのパーミッションはどうなってるかというと:

[[email protected] ~]$ ls -lZ /run/lcstorage
合計 0
srwxrwxrwx. 1 lcstorage lcstorage unconfined_u:object_r:var_run_t:s0 0 11月 23 11:42 unicorn.sock

Z は SELinux のアクセス権限を表示するオプション。うん、よくわからん。SELinux が原因かどうかは /var/log/audit/audit.log を調べるとわかるらしい。再度 SELinux を有効にしてアクセスしてみてから:

[[email protected] ~]$ sudo cat /var/log/audit/audit.log | grep nginx | tail
type=SERVICE_STOP msg=audit(1574476367.153:1276): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=nginx comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'UID="root" AUID="unset"
type=SERVICE_START msg=audit(1574476367.207:1277): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=nginx comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'UID="root" AUID="unset"
type=AVC msg=audit(1574476403.391:1281): avc:  denied  { connectto } for  pid=2526 comm="nginx" path="/run/lcstorage/unicorn.sock" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0
type=SYSCALL msg=audit(1574476403.391:1281): arch=c000003e syscall=42 success=no exit=-13 a0=e a1=561f05479e28 a2=6e a3=7ffe9aa20e0c items=0 ppid=2522 pid=2526 auid=4294967295 uid=977 gid=975 euid=977 suid=977 fsuid=977 egid=975 sgid=975 fsgid=975 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=connect AUID="unset" UID="nginx" GID="nginx" EUID="nginx" SUID="nginx" FSUID="nginx" EGID="nginx" SGID="nginx" FSGID="nginx"
type=AVC msg=audit(1574476651.650:1290): avc:  denied  { connectto } for  pid=2526 comm="nginx" path="/run/lcstorage/unicorn.sock" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=1
type=SYSCALL msg=audit(1574476651.650:1290): arch=c000003e syscall=42 success=yes exit=0 a0=e a1=561f05479e28 a2=6e a3=7ffe9aa20e0c items=0 ppid=2522 pid=2526 auid=4294967295 uid=977 gid=975 euid=977 suid=977 fsuid=977 egid=975 sgid=975 fsgid=975 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=connect AUID="unset" UID="nginx" GID="nginx" EUID="nginx" SUID="nginx" FSUID="nginx" EGID="nginx" SGID="nginx" FSGID="nginx"
type=AVC msg=audit(1574477463.658:1309): avc:  denied  { connectto } for  pid=2526 comm="nginx" path="/run/lcstorage/unicorn.sock" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=1
type=SYSCALL msg=audit(1574477463.658:1309): arch=c000003e syscall=42 success=yes exit=0 a0=e a1=561f05479e28 a2=6e a3=7ffe9aa20e0c items=0 ppid=2522 pid=2526 auid=4294967295 uid=977 gid=975 euid=977 suid=977 fsuid=977 egid=975 sgid=975 fsgid=975 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=connect AUID="unset" UID="nginx" GID="nginx" EUID="nginx" SUID="nginx" FSUID="nginx" EGID="nginx" SGID="nginx" FSGID="nginx"
type=AVC msg=audit(1574477957.417:1347): avc:  denied  { connectto } for  pid=2526 comm="nginx" path="/run/lcstorage/unicorn.sock" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0
type=SYSCALL msg=audit(1574477957.417:1347): arch=c000003e syscall=42 success=no exit=-13 a0=e a1=561f05479e28 a2=6e a3=7ffe9aa20e0c items=0 ppid=2522 pid=2526 auid=4294967295 uid=977 gid=975 euid=977 suid=977 fsuid=977 egid=975 sgid=975 fsgid=975 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)ARCH=x86_64 SYSCALL=connect AUID="unset" UID="nginx" GID="nginx" EUID="nginx" SUID="nginx" FSUID="nginx" EGID="nginx" SGID="nginx" FSGID="nginx"

さぱーりわからん。けど、どうやら↓ここらしい。

type=AVC msg=audit(1574477957.417:1347): avc:  denied  { connectto } for  pid=2526 comm="nginx" path="/run/lcstorage/unicorn.sock" scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0

nginx が /run/lcstorage/unicorn.sock にアクセスしようとして denied になってるようだ。つまりここを何とかすればいいわけ。

SELinux の上のアクセスを許可する設定は、/var/log/audit/audit.log ファイルから audit2allow コマンドで作れるようだ。まず確認。

[[email protected] ~]$ sudo grep nginx /var/log/audit/audit.log | audit2allow

#============= httpd_t ==============

#!!!! This avc can be allowed using the boolean 'httpd_can_network_connect'
allow httpd_t glance_port_t:tcp_socket name_connect;

#!!!! This avc can be allowed using one of the these booleans:
#     httpd_can_network_connect, httpd_graceful_shutdown, httpd_can_network_relay, nis_enabled
allow httpd_t http_port_t:tcp_socket name_connect;
allow httpd_t unconfined_t:unix_stream_socket connectto;

設定用のファイルを作るにはこうする。

[[email protected] ~]$ sudo grep nginx /var/log/audit/audit.log | audit2allow -M nginx
[sudo] takatoh のパスワード:
******************* 重要 ********************
このポリシーパッケージを有効にするには、以下を実行して下さい:

semodule -i nginx.pp

指示にあるようにして、SELinux に設定する。

[[email protected] ~]$ sudo semodule -i nginx.pp

さてこれでどうだろう。はたして、別のマシンからブラウザでアクセスしてみると、ちゃんと File not found. って表示された。なんどもいうけどこれが(ry。

つぎは web アプリをサービスとして登録する。/etc/systemd/system ディレクトリの下に lcstorage.service ファイルを作る。

[Unit]
Description=LatherCraft storage service
After=network.target

[Service]
Type=forking
PIDFile=/home/lcstorage/lcstorage/unicorn.pid
ExecStart=/usr/local/bin/bundle exec unicorn -c unicorn.conf -E production -D
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -QUIT $MAINPID
WorkingDirectory=/home/lcstorage/lcstorage
User=lcstorage
Group=lcstorage

[Install]
WantedBy=multi-user.target

これで起動してみる。

[[email protected] system]$ sudo systemctl start lcstorage

あれ?おかしい。プロンプトが戻ってこない。ほかのターミナルからステータスを見てみると:

[[email protected] lcstorage]$ systemctl status lcstorage
● lcstorage.service - LatherCraft storage service
   Loaded: loaded (/etc/systemd/system/lcstorage.service; disabled; vendor pres>
   Active: activating (start) since Sat 2019-11-23 12:57:57 JST; 1min 14s ago
  Process: 3931 ExecStart=/usr/local/bin/bundle exec unicorn -c unicorn.conf -E production -D (code=exited, status=0/SUCCESS)
    Tasks: 6 (limit: 26213)
   Memory: 31.4M
   CGroup: /system.slice/lcstorage.service
           ├─3936 unicorn master -c unicorn.conf -E production -D  production -D
           ├─3939 unicorn worker[0] -c unicorn.conf -E production -D  productio>
           └─3942 unicorn worker[1] -c unicorn.conf -E production -D  productio>
11月 23 12:57:57 rollo systemd[1]: Starting LatherCraft storage service…
11月 23 12:57:58 rollo systemd[1]: lcstorage.service: Can't convert PID files /home/lcstorage/lcstorage/unicorn.pid O_PATH file descriptor to proper file descriptor: Permission denied
11月 23 12:57:58 rollo systemd[1]: lcstorage.service: Can't convert PID files /home/lcstorage/lcstorage/unicorn.pid O_PATH file descriptor to proper file descriptor: Permission denied

pid ファイルにアクセスできないっぽい?じゃあ、場所を変えてみようか。/home/lcstorage/lcstorage/unicorn.conf と /etc/systemd/system/lcstorage.service の両方で pid ファイルを作る場所を /run に変えてみた。

でもまだダメ。もとに戻す。もう一度やってみてもこうなる。

[[email protected] system]$ sudo systemctl start lcstorage
Job for lcstorage.service failed because a timeout was exceeded.
See "systemctl status lcstorage.service" and "journalctl -xe" for details.

で、SELinux を無効にしてやってみた。

[[email protected] system]$ sudo setenforce 0
[[email protected] system]$ getenforce
Permissive
[[email protected] system]$ sudo systemctl start lcstorage

あ、これだとすんなりいく。ブラウザからアクセスしてもうまくいった。またお前か、SELinux!

さっきとおなじように /var/log/audit/audit.log を調べてみるとこうなってた。

type=AVC msg=audit(1574483152.115:1720): avc:  denied  { open } for  pid=1 comm="systemd" path="/home/lcstorage/lcstorage/unicorn.pid" dev="dm-2" ino=24382 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:user_home_t:s0 tclass=file permissive=1

やっぱり pid ファイルにアクセスできないみたいだ。ポリシーを作ってやる。

[[email protected] ~]$ sudo grep unicorn /var/log/audit/audit.log | audit2allow -M unicorn
[[email protected] ~]$ sudo semodule -i unicorn.pp

これでどうだろう。

[[email protected] ~]$ sudo setenforce 1
[[email protected] ~]$ getenforce
Enforcing
[[email protected] ~]$ sudo systemctl start lcstorage

お、うまくいったっぽい。ブラウザからアクセスしても大丈夫だった。

最後に。マシンを起動した時に自動起動するようにする。

[[email protected] ~]$ sudo systemctl enable lcstorage
Created symlink /etc/systemd/system/multi-user.target.wants/lcstorage.service → /etc/systemd/system/lcstorage.service.

はぁ、長かった。

カテゴリー: CentOS, Ruby | コメントする

Ruby 製アプリを Unicorn で動かす

昨日に引き続きデプロイの続きをするよ。今日の作業はまず Unicorn でアプリを動かすことだ。

Gemfile に unicorn を書き足して bundle install。

source "https://rubygems.org"

gem 'sinatra'
gem 'httpclient'
gem 'json'
gem 'filestorage'
gem 'unicorn'
[[email protected] lcstorage]$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/………….
Resolving dependencies…
Using bundler 2.0.2
Using filestorage 0.1.0
Using httpclient 2.8.3
Using json 2.2.0
Fetching kgio 2.11.2
Installing kgio 2.11.2 with native extensions
Using mustermann 1.0.3
Using rack 2.0.7
Using rack-protection 2.0.7
Fetching raindrops 0.19.0
Installing raindrops 0.19.0 with native extensions
Using tilt 2.0.10
Using sinatra 2.0.7
Fetching unicorn 5.5.1
Installing unicorn 5.5.1 with native extensions
Bundle complete! 5 Gemfile dependencies, 12 gems now installed.
Bundled gems are installed into ./vendor/bundle

Unicorn の設定ファイル unicorn.conf を書く。

listen "9000"
worker_processes 2
working_directory "/home/lcstorage/lcstorage"
pid "/home/lcstorage/lcstorage/unicorn.pid"
stdout_path "/home/lcstorage/lcstorage/unicorn.log"
stderr_path "/home/lcstorage/lcstorage/unicorn.log"
preload_app true

これでいいはず。試しに起動してみる。

[[email protected] lcstorage]$ bundle exec unicorn -c unicorn.conf -E production

昨日と同じく、別のコンソールからアクセス。

[[email protected] ~]$ curl http://localhost:9000/
File not found.[[email protected] ~]$ 
[[email protected] ~]$ curl http://localhost:9000/path/to/file
File not found.[[email protected] ~]$

うん、ちゃんと File not found. が返ってきてる。昨日も書いたけど、返すファイルがまだ無いのでこれは正しい動作だ。

さて、あとは Nginx との連携だけど、これはエントリを分ける。というわけでとりあえずここまで。

カテゴリー: CentOS, Ruby | コメントする

CentOS 8 のマシンに Ruby 製 web アプリをデプロイしようとしたら bundle install でコケた

前にやった時もそうだったような気がするんだよなぁ。

詳しい話に入る前に、作業環境を整理しよう。web アプリのデプロイ先は、この間買った新しい マシン rollo (OS は CentOS 8)。これにいつもの作業用メインマシン apostrophe(OS は Ubuntu 16.04 LTS)から ssh で接続して作業してる。rollo 上での作業はアプリの専用ユーザ lcstorage で行った。

まずは、BitBucket から git clone した。

GitHub じゃないのは公開したくないプライベートなプロジェクトだから。オープンにしてもいいプロジェクトは GitHub、そうでないのは BitBucket と使い分けてる。

閑話休題。git clone が終わったので、必要なライブラリをインストールすべく bundle install したらコケた。

[[email protected] lcstorage]$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/………….
Using bundler 2.0.2
Fetching filestorage 0.1.0
Installing filestorage 0.1.0
Fetching httpclient 2.8.3
Installing httpclient 2.8.3
Fetching json 2.2.0
Installing json 2.2.0 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

current directory:
/home/lcstorage/lcstorage/vendor/bundle/ruby/2.5.0/gems/json-2.2.0/ext/json/ext/generator
/usr/bin/ruby -r ./siteconf20191122-22908-wlblo2.rb extconf.rb
mkmf.rb can't find header files for ruby at /usr/share/include/ruby.h

extconf failed, exit code 1

Gem files will remain installed in
/home/lcstorage/lcstorage/vendor/bundle/ruby/2.5.0/gems/json-2.2.0 for
inspection.
Results logged to
/home/lcstorage/lcstorage/vendor/bundle/ruby/2.5.0/extensions/x86_64-linux/2.5.0/json-2.2.0/gem_make.out

An error occurred while installing json (2.2.0), and Bundler cannot
continue.
Make sure that gem install json -v '2.2.0' --source 'https://rubygems.org/'
succeeds before bundling.

In Gemfile:
  json

どうも json gem が拡張ライブラリで、ビルドできなくてコケてるようだ。いろいろググって試行錯誤した結果、つぎのパッケージを dnf install したらできた。

  • gcc
  • make
  • ruby-devel
  • rpm-build

gcc や make が入ってなかったのか……

ともあれこれでインストールはできた。必要な設定ファイルやらディレクトリやらを作って、試しに起動してみた。

[[email protected] lcstorage]$ bundle exec rackup
[2019-11-22 22:32:38] INFO  WEBrick 1.4.2
[2019-11-22 22:32:38] INFO  ruby 2.5.3 (2018-10-18) [x86_64-linux]
[2019-11-22 22:32:38] INFO  WEBrick::HTTPServer#start: pid=25617 port=9292

起動は大丈夫のようだ。9292番のポートは開けてないので、別のターミナルから別のユーザで rollo に入ってアクセスしてみた。

[[email protected] ~]$ curl http://localhost:9292/
File not found.[[email protected] ~]$ 
[[email protected] ~]$ curl http://localhost:9292/path/to/file
File not found.[[email protected] ~]$

返すファイルがないので File not found. が帰ってくるのは正しい動作。どうやら大丈夫のようだ。

明日は Nginx を介して外部からアクセスできるようにする予定。

カテゴリー: CentOS, Ruby | コメントする