UbuntuにRMagickをインストール

環境

takatoh@apostrophe $ cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04.5 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.5 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
takatoh@apostrophe $ ruby -v
ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]

↓このページによると、ImageMagick がバージョン7以降だと RMagick は使えないらしい。

 cf. RMagickのインストールで奈落に落ちた – Qiita

takatoh@apostrophe $ convert -version
Version: ImageMagick 6.8.9-9 Q16 x86_64 2018-09-28 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules OpenMP
Delegates: bzlib cairo djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png rsvg tiff wmf x xml zlib

6.8.9 だ、ラッキー。

依存パッケージとRMagickのインストール

まずは依存パッケージから。

takatoh@apostrophe $ sudo apt install libmagickcore-dev libmagickwand-dev

そして、RMagick。

takatoh@apostrophe $ sudo gem install rmagick
Building native extensions. This could take a while…
Successfully installed rmagick-2.16.0
Parsing documentation for rmagick-2.16.0
Installing ri documentation for rmagick-2.16.0
Done installing documentation for rmagick after 4 seconds
1 gem installed

完了。

さくらのVPSのサイトをHTTPS化

さくらの VPS で運用しているサイト(Railsアプリ)を Let’s Encrypt で HTTPS 化した。言っとくけどこのブログじゃないよ。

HTTPのポートを開放

まず、HTTPS のポート 443 を開放する。/etc/sysconfig/iptables ファイルを編集。

[takatoh@tk2-254-36564 ~]$ cd /etc/sysconfig
[takatoh@tk2-254-36564 sysconfig]$ sudo vim iptables

つぎの行を追加。

-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT

iptables を再起動。

[takatoh@tk2-254-36564 sysconfig]$ sudo service iptables restart
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
iptables: Applying firewall rules: [ OK ]
iptables: Loading additional modules: ip_conntrack_ftp [ OK ]

certbot-auto のセットアップと証明書の自動生成

「certbot-auto」は Let’s Encrypt が提供しているクライントツールで、SSL証明書を取得したり延長したりできる。ここでは、最新版を取得する。

[takatoh@tk2-254-36564 bin]$ sudo wget https://dl.eff.org/certbot-auto
--2019-01-13 09:41:36-- https://dl.eff.org/certbot-auto
dl.eff.org をDNSに問いあわせています… 151.101.72.201, 2a04:4e42:36::201
dl.eff.org|151.101.72.201|:443 に接続しています… 接続しました。
HTTP による接続要求を送信しました、応答を待っています… 200 OK
長さ: 63562 (62K) [application/octet-stream]
`certbot-auto' に保存中

100%[======================================>] 63,562 --.-K/s 時間 0.002s

2019-01-13 09:41:39 (24.3 MB/s) - `certbot-auto' へ保存完了 [63562/63562]

[takatoh@tk2-254-36564 bin]$ sudo chmod 700 /usr/bin/certbot-auto

いまインストールした certbot-auto を使って、証明書を自動生成する。

[takatoh@tk2-254-36564 ~]$ sudo certbot-auto certonly --webroot -w /var/www/lathercraft/public -d www.lathercraft.net --email [email protected]

途中、いろんなパッケージをインストールしたりするのでy(yes)を入力する。しばらくすると利用規約が表示されるので、A(agree)を入力。最後に↓こんなメッセージが出ればOK。

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/www.lathercraft.net/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/www.lathercraft.net/privkey.pem
Your cert will expire on 2019-04-12. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew all of your certificates, run
"certbot-auto 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

- We were unable to subscribe you the EFF mailing list because your
e-mail address appears to be invalid. You can try again later by
visiting https://act.eff.org.

……じゃないな、e-mail が invalid だと言ってる。あとから試せるとも言ってるので、とりあえず先に進む。この時点で証明書類はこんな感じになっている。

[takatoh@tk2-254-36564 ~]$ sudo ls -l /etc/letsencrypt/live/www.lathercraft.net/
合計 4
-rw-r--r-- 1 root root 692 1月 13 09:53 2019 README
lrwxrwxrwx 1 root root 43 1月 13 09:53 2019 cert.pem -> ../../archive/www.lathercraft.net/cert1.pem
lrwxrwxrwx 1 root root 44 1月 13 09:53 2019 chain.pem -> ../../archive/www.lathercraft.net/chain1.pem
lrwxrwxrwx 1 root root 48 1月 13 09:53 2019 fullchain.pem -> ../../archive/www.lathercraft.net/fullchain1.pem
lrwxrwxrwx 1 root root 46 1月 13 09:53 2019 privkey.pem -> ../../archive/www.lathercraft.net/privkey1.pem

Nginxの設定

SSL 対応にする。こんなふうに書き換える。

    #listen      80;
    listen      443 ssl;

    ssl_certificate      /etc/letsencrypt/live/www.lathercraft.net/cert.pem;
    ssl_certificate_key  /etc/letsencrypt/live/www.lathercraft.net/privkey.pem;

Nginx を再起動。

[takatoh@tk2-254-36564 conf.d]$ sudo service nginx restart
Stopping nginx: [ OK ]
Starting nginx: [ OK ]

これでOKのはず。まだアプリが SSL 対応していないのでバナー画像に https でアクセスしてみたら、ちゃんと表示された。なのでここまではOKのようだ。

RailsアプリのSSL対応

これは簡単。config/envronments/production.rb ファイルのつぎの箇所を修正すればいい。

# config.force_ssl = true
config.force_ssl = true

コメントアウトしてあるのを外すだけだ。そして再起動。

[takatoh@tk2-254-36564 environments]$ sudo service unicorn_lathercraft restart
reloaded OK

OK。大丈夫そうだ。

httpをhttpsにリダイレクト

最後に、http でのアクセスを https にリダイレクトする設定をする。Nginx の設定に戻ってつぎの設定を追加する。

server {
    listen       80;
    server_name  www.lathercraft.net;
    return       301 https://www.lathercraft.net;
}

Nginx を再起動して完了。

証明書の自動更新設定

Let’s Encrypt の証明書は有効期限が3ヶ月と短いので、自動更新するように設定する。更新は certbot-auto renew コマンドでできるので、これを root ユーザの cron に登録する。

[takatoh@tk2-254-36564 ~]$ sudo -s
[root@tk2-254-36564 takatoh]# crontab -l
no crontab for root
[root@tk2-254-36564 takatoh]# crontab -e
0 4 * * 0 certbot-auto renew --post-hook "service unicorn_lathercraft restart" > /dev/null 2> /dev/null

これで毎週月曜日の午前4時に更新するようになる。

[追記]

上の、Nginx のリダイレクトの設定では、http でのアクセスはどんなパスでも全て https のルートにリダイレクトされてしまう。なので、つぎのように変更した。

server {
    listen       80;
    server_name  www.lathercraft.net;

    location ~ ^/(.*)$ {
        return 301 https://www.lathercraft.net/$1;
    }
}

これで各ページも https にリダイレクトされるようになった。

Windows10その後

というか iTunes のその後、というか。

結局、Windows を再インストールして、アプリを一つずつインストールしながら iTunes がちゃんと動くかどうかを確認していった。ついでに、先週のエントリを書いた時点では気づかなかったけど、Dropbox の同期もできていなかったので、これも確認しながら。

で、どうやら RLogin という SSH 接続に使っているターミナルクライアントが怪しいということになって、これを除いた構成で様子を見ることにした。ところが、再インストール直後は大丈夫だった iTunes と Dropbox がしばらく経つといつの間にかやっぱり繋がらなくなっている。どうも、少なくとも RLogin 単独のせいではないようで、なぜつながらないのかさっぱりわからない。

そういうわけなので、montana で iTunes と Dropbox を動かすのは諦めて、ノートPCの sofa で動かすことにした。sofa のストレージは SSD で容量が少ないので、samba サーバ(wplj)に共有フォルダを新しく作って、それを sofa の M:ドライブに割り当てて音楽保管用のフォルダを作った(なにせアルバム1000枚、60GBもあるので)。この構成だと、家の WiFi の外では使えないけど、それは諦めることにした。

というわけで、montana は WEB ブラウジングとゲーム用のマシンになった。ゲームのセーブデータは全部消えたけどな(←こないだも言った)!

iTunes Storeにつながらない

Windows10 のセットアップが終わって、一息ついたと思ったら、iTunes Store につながらない。「ネットワークの接続を確認して、やり直してください。」と言われる。CD からインポートした曲は聴けるんだけど(当然)、Store から購入した曲が聴けない。これじゃ、何のために Windows の再インストールをしたんだかわからないじゃないか。

たしか昨日、Windows のインストールが終わったあと、最初にインストールしたのが iTunes だ。その時はちゃんとつながったはずだ。ということは、そのあとにインストールしたアプリが悪さをしてるか、何か設定が変わってしまったか。

はぁ、一つずつ消して確かめてみるか……

[追記]

iTunes 以外のアプリを一つずつ消しながら確かめてみた。結果、iTunes 以外の、あとからインストールしたアプリを全部消しても、さらには iTunes 自体を再インストールしてもつながらなかった。たぶん、アプリのインストールをしてるどこかで何かの設定が変わっちゃったんだ。

結局、Windows の再インストールしかないか。

Windows10を再インストールした

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

先日こわれて(こわして)しまった montana の Windows10、アマゾンで頼んだインストールメディア(DVD)が届いた。届いた Windows には LAN アダプタがついていた、というか LAN アダプタに Windows10 がついていたというのか。そういえば注文した時にバンドル版だと書いてあったような気がする。それにしてもこの LAN アダプタ、10/100Mbps なんだけど今時こんなのあるんだね。誰が使うんだろう?

それはともかく、Windows10 の再インストールだ。インストール自体はインストーラに従っていけばすんなり終わるので、詳細は割愛する。ただ、デフォルトでは「ドキュメント」ほかいくつかのフォルダが OneDrive 上に保存されるようになっている。この点だけ、ローカルドライブに保存するように変更した。

まず、画面右下の OneDrive のアイコン(雲のアイコン)を右クリックして「設定」を選ぶ。「自動保存」タブの「フォルダの更新」ボタンをクリックして出てくるウィンドウに「デスクトップ」と「写真」、「ドキュメント」があるので、それぞれ「保護の停止」をクリックする。これで OneDrive じゃなくてローカルドライブに保存するようになる。

あとはアプリのインストールだけど、使ってるのはほとんどフリーソフト(例外は iTunes と MS Office、B’s Recorder くらい)なので、Chocolatey を使ってインストールした。コマンド一発でダウンロードからインストールまでしてくれるので楽でいい。

ただ、Ruby だけは別にインストールした。というのは Chocolatey でインストールすると Devkit が含まれていないものがインストールされるからだ。これだとネイティブなライブラリ(RDiscount とか)がインストールできない。なので、RubyInstaller のダウンロードページから Devkit を含んだインストーラをダウンロードしてインストールした。

さて、これで一通りのセットアップは終了。アイコンがごちゃごちゃしていたデスクトップもさっぱりしたので、そこはよかったかも。

ゲームのセーブデータは全部消えたけどな!

Windows10がこわれた

というかこわしちゃった、というか。新年早々、なんて運が悪いんだ。

こわれたのは Windows10 マシンの montana なんだけど、経緯はこうだ。しばらく前からちょっと調子が悪かった。DropBox が同期できないし、iTunes のアップデートにも失敗する。どうもネットにうまくつながらなくて失敗してるらしいんだけど、一方でブラウザ等ではなんの問題もなく使えてた。とはいえ、不便もあったし、連休中でちょうどいいので、以前作ってあった回復ドライブ(USBメモリ)をつかって、インストールし直そうとしたわけだ。

で、いったん電源を落として、回復ドライブの USBメモリをさしてスイッチオン。F12キーを押してブートメニュー画面に入ってから、「USB Storage Drive」を選択。これで回復ドライブから起動する。あとはメニューに従っていくと、「このPCを回復しています」というメッセージと一緒に進捗を示すパーセンテージが表示される。

あとは待つだけかとおもったら、5%くらいの進捗のところで、「PCを初期状態に戻すときに問題が発生しました。変更は行われませんでした。」というメッセージが!

この時点で選択肢は「キャンセル」しか無い。仕方なくキャンセルすると、起動したあとの最初の方の画面に戻ってやり直し。ところが結局は同じ結果になる。何度繰り返しても同じ。

試しに USBドライブを抜いて起動してみたけど、ファイルが削除されてしまったらしくハードディスクからは起動できず。ここで手詰まり。

というわけで、Windows10 がこわれてしまった。何が回復ドライブだ。ふざけんな!

Gem in a Boxでオレオレgemサーバをたてる

自分でしか使わない、外部には公開できないような gem がいくつかあるので、gem サーバをたてることにした。Gem in a Box (geminabox)は、プライベートな gem サーバだ。gem コマンドでインストールして、ちょっと設定ファイルを書くだけで使えるようになる。

じゃ、いってみよう。

環境

  • Ubuntu 16.04 LTS
  • Ruby 2.3.1p112

インストールと設定

前述したように gem コマンドでインストールできる。

takatoh@wplj $ sudo gem install geminabox

~/geminabox ディレクトリを作って、設定ファイルを書く。

takatoh@wplj $ mkdir ~/geminabox
takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ vim config.ru

設定ファイルはこんな感じ、っていうかこれだけ。

require "geminabox"

Geminabox.data = "/home/takatoh/geminabox/data"
run Geminabox::Server

gem ファイルが格納される data ディレクトリを作る。

takatoh@wplj $ mkdir data

これで Gem in a Box 自体のインストールと設定は完了。

Supervisord で管理

さて、これをデーモンにする必要があるんだけど、昨日 Supvervisord を試したので今日も同じようにしてみる。設定ファイル /etc/supervisord.d/geminabox.ini をつぎのように書いた。

[program:geminabox]
command=/usr/local/bin/rackup -p 9999
process_name=geminabox
user=takatoh
directory=/home/takatoh/geminabox
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/geminabox/geminabox.log
stdout_logfile_maxbytes=1M
stdout_logfile_backups=7
stdout_capture_maxbytes=1M
redirect_stderr=true

これで OK のはず。動かしてみよう。

takatoh@wplj $ supervisorctl reload
Restarted supervisord
takatoh@wplj $ supervisorctl status
geminabox RUNNING pid 26835, uptime 0:00:08
sulaiman RUNNING pid 26836, uptime 0:00:08

ちゃんと動いてるようだ。

Nginxのバーチャルホスト設定

gembox というホスト名でアクセスできるように Nginx を設定する。/etc/nginx/sites-available/gembox が設定ファイルだ。

upstream geminabox {
    server 127.0.0.1:9999;
}

server {
    # port
    listen      80;

    # server name
    server_name gembox;

    # document root
    root        /home/takatoh/geminabox;

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

    # log files
    access_log /var/log/nginx/gembox/access.log combined;
    error_log  /var/log/nginx/gembox/error.log  warn;

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

 
    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://geminabox;
    }
}

/etc/nginx/sites-enabled/gembox にリンクをはる。

takatoh@wplj $ sudo ln -s /etc/nginx/sites-available/gembox sites-enabled/gembox

ログファイル用のディレクトリを作成。

takatoh@wplj $ sudo mkdir /var/log/nginx/gembox

そして、Ngixn をリロード。

takatoh@wplj $ sudo systemctl reload nginx

これで完了。ほかのマシンからブラウザで http://gembox/ にアクセスすると、期待どおり Gem in a Box のページにアクセスできた。

[追記]

アクセスはできたけど、試しに gem ファイルを1つアップロードしてみたら「uninitialized constant Gem::Util」というエラーが出てしまった。なんだこりゃ?

[追記2]

解決編。rubygems 自体が古いのが原因だったようだ。

takatoh@wplj $ sudo gem update --system
takatoh@wplj $ gem -v
3.0.1

念のため、データ置き場を作りなおす。

takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ rm -rf data
takatoh@wplj $ mkdir data

リスタート。

takatoh@wplj $ supervisorctl restart geminabox
geminabox: stopped
geminabox: started

これで無事、オレオレgemをアップロードできるようになった。

Supervisorで自作プログラムをデーモン化

自作のプログラムやスクリプトをデーモン化したい場合がある。でも、デーモンとして動作するようには作っていない……そういう時には Supervisor の出番だ。

Supervisor は Python 製のツールで、デーモンとして動作するように作られていないプログラムでもデーモン化できる。Supervisor 自体は root 権限でデーモンとして動かす必要があるけど、その下にぶら下がるプログラムはユーザー権限で管理できるのがいい点だ。

今日は、Ubuntu マシンの wplj に Supervisor をインストールして、以前 Go で作った画像アップローダを動かしてみる。

環境

  • Ubuntu 16.04 LTS
  • Python 2.7.12

Supervisorのインストールといろいろ下準備

Supervisor 自体は pip でインストールできる。

takatoh@wplj $ sudo pip install supervisor

/etc/supervisord.conf にデフォルトの設定ファイルを生成。

takatoh@wplj $ sudo echo_supervisord_conf > /etc/supervisord.conf
-bash: /etc/supervisord.conf: 許可がありません

あれ、sudo つけてるのになんでだ?よくわからないけど sudo -s してからやってみよう。

takatoh@wplj $ sudo -s
root@wplj # echo_supervisord_conf > /etc/supervisord.conf

今度はできた。つぎ、include 設定ファイル用のディレクトリを作成。

root@wplj # mkdir /etc/supervisord.d

supervisord 自体のはくログ周りの設定。デフォルトでは /tmp/supervisord.log に吐き出すことになっているので、設定ファイル /etc/supervisord.conf を修正して /var/log/supervisord.log に吐くようにする。

[supervisord]
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile=/var/log/supervisord.log

PID ファイルの設定。/var/run 以下に置くように変更。

;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
pidfile=/var/run/supervisord.pid

/etc/supervisord.d 以下のファイルを include するように変更。これで設定ファイルの修正は終了。

[include]
files = supervisord.d/*.ini

supervisord自体のサービス登録

/etc/systemd/system/supervisord.service ファイルを作成する。

[Unit]
Description=Supervisor process control system for UNIX
Documentation=http://supervisord.org/
After=network.target

[Service]
ExecStart=/usr/local/bin/supervisord -n -c /etc/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/local/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=50s

[Install]
WantedBy=multi-user.target

起動と自動起動の登録

root@wplj # systemctl start supervisord
root@wplj # systemctl enable supervisord.service
Created symlink from /etc/systemd/system/multi-user.target.wants/supervisord.service to /etc/systemd/system/supervisord.service.

自作プログラムの配置

Go で作った画像アップローダ sulaiman を配置する。こんなふうにした。

takatoh@wplj $ tree ~/sulaiman
/home/takatoh/sulaiman
├── config.json
├── photos
│   ├── img
│   └── thumb
├── static
│   ├── css
│   │   └── style.css
│   ├── html
│   │   └── index.html
│   └── js
│   └── sulaiman.js
└── sulaiman

試しに動かしてみる。

takatoh@wplj $ ./sulaiman
_ _ / // /
/ // / \/ _ \
//__////_/ v3.3.5
High performance, minimalist Go web framework
https://echo.labstack.com
_________________________________O/_

O\
⇨ http server started on [::]:9099

大丈夫そうだ。

プロセス管理登録と起動確認

配置したプログラムを supervisord の管理下に登録する。/etc/supervisord.d 以下に設定ファイル sulaiman.ini を作る。

[program:sulaiman]
command=/home/takatoh/sulaiman/sulaiman
process_name=sulaiman
user=takatoh
directory=/home/takatoh/sulaiman
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/sulaiman/sulaiman.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=7
stdout_capture_maxbytes=1MB
redirect_stderr=true

これで OK のはずだ。確認してみよう。

takatoh@wplj $ supervisorctl start sulaiman
error: , [Errno 13] Permission denied: file: /usr/lib/python2.7/socket.py line: 228

はぁ?どういうこと?

問題解決

ソケット周りでエラーが出てるようだ。権限がないとかいってる。supervisord の設定ファイルを眺めてみると、ソケットファイルのモードを設定する項目が見つかった。これを変更してみよう。

[unix_http_server]<br>file=/tmp/supervisor.sock   ; the path to the socket file<br>;chmod=0700                 ; socket file mode (default 0700)<br>chmod=0777

supervisord をリロード。

takatoh@wplj $ sudo systemctl reload supervisord

確認。

takatoh@wplj $ supervisorctl status sulaiman
sulaiman RUNNING pid 19356, uptime 0:00:22

こんどは OK。

これで、プログラムやスクリプトを簡単にデーモン化できるようになった。

参考ページ

 cf. Supervisorで簡単にデーモン化 – Qiita

「ソフトウェアエンジニアならば1時間以内に解けなければいけない5つの問題」をRubyで

ちょっと、というか結構古いけど 「ソフトウェアエンジニアならば1時間以内に解けなければいけない5つの問題」 というのを見つけた。

 cf. 1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に – SOFTANTENNA BLOG

大元のページはもうなくなっているようだけど、上のページに問題が載っているので Ruby でやってみた。

問題1

forループ、whileループ、および再帰を使用して、リスト内の数字の合計を計算する3つの関数を記述せよ。

def solv1(ary)
  result = 0
  for i in ary
    result += i
  end
  result
end

def solv2(ary)
  result = 0
  while ary.size > 0
    result += ary.shift
  end
  result
end

def solv3(ary)
  if ary.empty?
    0
  else
    x = ary.shift
    x + solv3(ary)
  end
end

puts solv1([1,2,3,4,5])
puts solv2([1,2,3,4,5])
puts solv3([1,2,3,4,5])

問題2

交互に要素を取ることで、2つのリストを結合する関数を記述せよ。例えば [a, b, c]と[1, 2, 3]という2つのリストを与えると、関数は [a, 1, b, 2, c, 3]を返す。

def solv(a1, a2)
  result = []
  until a1.empty?
    result << a1.shift
    result << a2.shift
  end
  result
end

p solv(['a', 'b', 'c'], [1, 2, 3])

問題3

最初の100個のフィボナッチ数のリストを計算する関数を記述せよ。定義では、フィボナッチ数列の最初の2つの数字は0と1で、次の数は前の2つの合計となる。例えば最初の10個のフィボナッチ数列は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34となる。

require 'pp'

def fib(a, b, acc, n)
  if n == 0
    acc
  else
    acc << a
    fib(b, a + b, acc, n - 1)
  end
end

def solv
  fib(0, 1, [], 100)
end

pp solv

問題4

正の整数のリストを与えられたとき、数を並び替えて可能な最大数を返す関数を記述せよ。例えば、[50, 2, 1, 9]が与えられた時、95021が答えとなる。

def solv(ary)
  ary.map{|x| x.to_s }.sort.reverse.join("").to_i
end

puts solv([50, 2, 1, 9])

問題5

1,2,…,9の数をこの順序で、”+”、”-“、またはななにもせず結果が100となるあらゆる組合せを出力するプログラムを記述せよ。例えば、1 + 2 + 34 – 5 + 67 – 8 + 9 = 100となる 。

def combi(ary)
  if ary.size == 1
    ary
  else
    result = []
    x = ary.shift
    c = combi(ary)
    ["+", "-", ""].each do |op|
      result += c.map{|e| x + op + e }
    end
    result
  end
end

def solv
  a = [1,2,3,4,5,6,7,8,9].map{|n| n.to_s }
  result = []
  combi(a).each do |e|
    if eval(e) == 100
      result << e
    end
  end
  result
end

solv.each do |e|
  puts e + " = 100"
end

俺はソフトウェアエンジニアじゃないけど、どうにか1時間以内に5問ともできた。一番難しかったのは問題5だけど、意外にてこずったのは問題1。Ruby の for の使い方(というか for があること自体)を忘れていて、結局ここだけググった。

sshで接続できるようにする

bigswifty を WiMAX に接続したので、他のマシンとはネットワーク的に切り離されてしまった。まぁ、これは意図した通りなんだけど、ssh で接続できないのも不便なので、インターネット経由で接続できるように設定する。

ここからは bitswifty 上での作業。

sshdの設定

ポートを変更。

Port 12345

root でのログインを禁止。

PermitRootLogin no

設定を反映するために sshd を再起動。

[lcstorage@bigswifty ~]$ sudo systemctl restart sshd

ファイアウォールの設定

ポートを開ける。

[lcstorage@bigswifty ~]$ sudo firewall-cmd --add-port=12345/tcp --zone=public --permanent
success

設定をリロード。

[lcstorage@bigswifty ~]$ sudo firewall-cmd --reload
success

WiMAX端末のポートマッピング

192.168.100.1 にブラウザで接続して、設定ページから、ファイアウォール設定→ポートマッピングと進んで、WAN ポートの12345 を bitswifty の12345 番ポートに接続するようにする。と、ここで気が付いたんだけど bigswifty のポートは変更しなくても良かったんじゃないか?まぁいいか。

接続テスト

別のマシンからインターネット経由で ssh 接続してみると、無事接続できた。

公開鍵での認証

認証方法をパスワード認証から公開鍵認証に切り替える。公開鍵は GitHub からもってきた。

[lcstorage@bigswifty ~]$ mkdir .ssh
mkdir: ディレクトリ `.ssh' を作成できません: ファイルが存在します
[lcstorage@bigswifty ~]$ cd .ssh
[lcstorage@bigswifty .ssh]$ wget -O authorized_keys https://github.com/takatoh.keys
--2018-12-15 05:32:26--  https://github.com/takatoh.keys
github.com (github.com) をDNSに問いあわせています... 192.30.255.112, 192.30.255.113
github.com (github.com)|192.30.255.112|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [text/plain]
`authorized_keys' に保存中

    [ <=>                                   ] 381         --.-K/s 時間 0s

      2018-12-15 05:32:27 (2.28 MB/s) - `authorized_keys' へ保存終了 [381]

[lcstorage@bigswifty .ssh]$ chmod 600 authorized_keys
[lcstorage@bigswifty .ssh]$ ls -al
合計 12
drwx------.  2 lcstorage lcstorage   48 12月 15 05:32 .
drwx------. 19 lcstorage lcstorage 4096 12月 15 04:34 ..
-rw-------   1 lcstorage lcstorage  381 12月 15 05:32 authorized_keys
-rw-r--r--.  1 lcstorage lcstorage  185 12月  4 03:56 known_hosts

接続テスト

再び、別のマシンから接続テスト。ちゃんと公開鍵認証で接続できた。

パスワード接続を禁止

最後に、もう一度 /etc/ssh/sshd_config ファイルを編集して、パスワード接続を禁止する。

PasswordAuthentication no

sshd を再起動。

[lcstorage@bigswifty .ssh]$ sudo systemctl restart sshd

これで完了。

参考ページ