SSHラッパーコマンドEsshのv1.0.0をリリースしました
Esshは、zsh補完やLuaスクリプトによる動的なコンフィグレーションなど、便利機能を実装した、sshのラッパーコマンドです。
ドキュメントをまとめたWebサイトも作成しました。
上記Webサイトのトップにasciinemaで撮ったターミナルオペレーションのデモを乗せましたので、そちらを見ていただければ、どういったものか大体のことはわかると思います。
開発の経緯
2015/11に以下の記事を書き、Zsshというコマンドを作成しました。
その後、CentOSのリポジトリにzssh
というパッケージが存在していたため、コマンド名をzssh
からessh
に変え、自分の利用にあわせて、適宜、機能の追加や変更を続けていました。そして、自分が使う上で必要十分な機能がそろって、大きな変更もなくなってきたので、この度これをv1.0.0
としてリリースすることにしました。なお2015/11時点のものとは仕様が大きく様変わりしており、以下に改めて、機能について説明します。
機能
EsshはGoで書かれたシングルバイナリのCLIツールで多機能sshコマンドとして利用できます。実装的には内部でssh
コマンドを実行するラッパーコマンドになっています。標準のsshコマンドでは使えない以下のような機能が利用できます。
- Luaによる設定ファイル。これによりSSH接続サーバの設定(ssh_config)をより動的に構築することができる。
- サーバ接続、切断時に発火するフックコマンドを設定できる。
- サーバにタグをつけられ、一覧をターミナルに出力できる。
- ZshとBash用の強力な補完を組み込みで提供。
- カレントディレクトリごとに設定ファイルの切り替え。
- Capistranoのような複数サーバに並行してコマンドを実行できるタスクランナー。
- 設定用のLuaコードはモジュールとしてGitリポジトリ上で共有できる。
一通りの機能に触れるためのチュートリアルを用意したので、利用の際はここから始めるとよいかと思います。
https://essh.sitespread.net/intro/ja/index.html
利用例
上記のチュートリアルには書いていないが、私個人が使っている機能などを中心にいくつか紹介します。
ログイン時にターミナルの色を変える
接続、切断時のフックコマンドhooks_before_connect
とhooks_after_disconnect
でターミナルの色を変えます。私は本番環境につなぐときは赤にしています。
-- ~/.essh/config.lua -- 事前にmacのターミナル設定でRedとBlackというプロファイルを作っておく local red_screen_command = "osascript -e 'tell application \"Terminal\" to set current settings of first window to settings set \"Red\"'" local black_screen_command = "osascript -e 'tell application \"Terminal\" to set current settings of first window to settings set \"Black\"'" host "webserver-01" { HostName = "192.168.56.32", Port = "22", User = "kohkimakimoto", description = "web server-01", hooks_before_connect = { red_screen_command }, hooks_after_disconnect = { black_screen_command }, tags = { "web", }, } host "webserver-02" { HostName = "192.168.56.33", Port = "22", User = "kohkimakimoto", description = "web server-02", hooks_before_connect = { red_screen_command }, hooks_after_disconnect = { black_screen_command }, tags = { "web", }, }
アプリケーションのデプロイ
リモートサーバにコマンドを実行します。以下はただのサンプルです。実環境ではもっと複雑なスクリプトを実行させています。
host "webserver-01" { HostName = "192.168.56.32", Port = "22", User = "kohkimakimoto", description = "web server-01", tags = { "web", }, } host "webserver-02" { HostName = "192.168.56.33", Port = "22", User = "kohkimakimoto", description = "web server-02", tags = { "web", }, } task "deploy" { backend = "remote", targets = {"web"}, prefix = true, parallel = true, script = [=[ echo "deploy app to $ESSH_HOSTNAME" # your deploy commands... echo "Done." ]=], }
以上です。日々のSSHライフのお供に、どうぞお使いください。m( )m
ReactNativeのiOSアプリをオフラインの実機で動かす
※2017-04-10現在のメモ。
先に結論。以下の#if !(TARGET_IPHONE_SIMULATOR)
で囲った部分のコードをios/AppName/AppDelegate.m
に仕込むといいです。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSURL *jsCodeLocation; #if !(TARGET_IPHONE_SIMULATOR) jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #else jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; #endif RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"AppName" initialProperties:nil launchOptions:launchOptions]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; return YES; }
経緯
ReactNativeでiOSアプリを作ってみてます。SwiftやObjective-Cで作ったアプリのように、開発中のアプリをUSBケーブルにつないだiPhoneにインストールして、動作確認してみようとしたら、うまくアプリが立ち上がらない。ドキュメントやGithubのissuesをみるとiPhoneが同じwifiにいないと動作しないらしいです。
「react native offline」とかで検索するとstackoverflowやgithubのissuesで、対処法が書いてあるが、今ひとつうまくいかない。というか、ReactNativeの更新が速いせいか、いまでは通用しない古い情報がまじっていてよくわからないです。で、Objective-Cは以前触ったこともあってソースが読めるので、直接ソースを追ってみました。それでわかったこととして
- 開発中ReactNativeは開発マシン上にhttpサーバを起動し、アプリはこのhttpサーバからJavaScriptコードを取得する。
- この仕組みのおかげで、開発中再ビルドなしで、変更を反映させられる。実機の場合も同様だが、オフラインだとhttpサーバに到達できず、エラーになる。
- ビルド時、リリースビルド用にJavaScriptを一つのファイルにまとめてアプリにバンドルするスクリプトが、XCodeのrun scriptで定義されている。
- リリースビルドの場合のみ、httpサーバからではなくファイルからJavaScriptを読むようにマクロで制御されている。
というわけで冒頭に記載したようにios/AppName/AppDelegate.m
内のコードを
#if !(TARGET_IPHONE_SIMULATOR) jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif
のようにして「シミュレータ以外のとき」という条件で、JavaScriptのロケーションを設定している変数を、リリースビルドのときと同様に、バンドルされたJavaScriptファイルを読みに行くよう上書きすればOKです。この場合当然、実機上で動かすと、再ビルドなしでコードの変更を反映させることはできなくなるので、それが必要なときは都度この部分を削除やコメントアウトするなりして、対応すればいいかな、と。今のところは。
OmnibusでPHPアプリケーションをRPMにパッケージングする
要約: Omnibusを使うとApacheとPHPをバンドルしたオールインワンなPHPアプリケーションのRPMパッケージを作れます。
最近CLIツールやAPIサーバなどはGoで書くようになって、PHPをさわる頻度が減ってきているのですが、それでもPHPの実行環境が不必要になることはなく、その個人的な一つの理由にAdminerがあります。これは2012年に一度ブログにも書いたのですが、PHPのシングルファイルをDocumentRootにおくだけで動作する、データベース用のWebUIです。
Adminer - PHPの1ファイルを置くだけで簡単に使えるDB管理ツール - オープンソースこねこね
現在でもメンテは続いているようで、今ではElasticsearchやMongoDBなどにも対応しているそうな。個人的にもずっと使い続けています。
ただ、前述のようにGoの適用範囲が広がってきたので、新しく立ち上げたサーバとかだと、Adminerを使う以外にApacheやPHPが必要ない環境もあります。後々の運用管理のことも考えてサーバ構築にはプロビジョニングツールを使っていることもあり、これ一つのために、ApacheとPHPを入れてhttpd.confとphp.iniを書き換えるレシピ書いて。。。てなことがやや面倒くさいです。
Adminerの機能単体でぱっとインストール、アンインストールできればいいかもしれない、と考えたので、omnibusを使ってApacheとPHPをバンドルしたオールインワンなPHPアプリケーションのRPMを作成してみました。omnibusについては以前ブログに書いたのでそちらを参照してください(CentOS用にSupervisor3.3.0のRPMパッケージを作成した - オープンソースこねこね )。今回の成果物は以下
$ sudo yum install https://github.com/kohkimakimoto/omnibus-adminer-server/releases/download/v0.3.0/adminer-server-0.3.0-1.el7.x86_64.rpm
でインストールできます。これだけで/opt/adminer-server
にApacheとPHPランタイムを含めたアプリケーションがインストールされます。これらはもちろんシステムワイドにあるApacheやPHPとは干渉しません。あとは、
$ sudo systemctl start adminer-server
とすればApacheが14200ポートで起動しますのでブラウザでhttp://localhost:14200/adminer.php
にアクセスすると
と画面がでます。
補足
- サービス設定は現状systemdのみの対応なので、このRPMはCentOS7限定です。initスクリプトを書けばCentOS6などにも対応できますが、自分が使わないので書いてません。
- 設定ファイルは
/etc/adminer-server
、adminer.phpなどのPHPファイルは/var/lib/adminer-server
以下に配置してあります。 - 今回はやってないがMySQLなどDBもバンドルすれば、いわゆるLAMPアプリケーションがパッケージ配布可能になるんじゃないかと。
あとがき
こんなことしなくても、今はDocker使えばいいかも、とも思いますが、Systemdにサービスを登録するところまでyum installl
でできるのでミドルウェア的なものを扱うのなら、RPMも便利ですよと。。。
テストやビルドスクリプトをDockerコンテナで実行させるための便利ツールを作った
ある程度複雑なプログラムだと、ローカル環境やCIサーバ環境など、どこでも動くようにテストを書くのが難しくなったりします。また、昨今のWebアプリケーションだと、デプロイ前に何らかのビルドプロセスが必要になることがほとんどで、依存物をインストールしたり、Webpackを動かしたり、Goのビルドを走らせたりします。こういうタスクもnodeやらGoに依存していて、複数の環境で差異なく動かすことを考えると、いろいろツライものがあります。
そこで、こういったテストやビルド処理はシェルスクリプトを書いて、Dockerコンテナ内で動かすことによって環境に対しての依存を解消していました。
たとえばGo言語の場合以下のようなテスト実行スクリプトtest_run.sh
を書いておきます。
#!/usr/bin/env bash set -eu go test $GOTEST_FLAGS $(go list ./... | grep -v vendor)
そしてこれをDockerコンテナで実行するためのスクリプトとして以下のようなtest.sh
を書きます。
#!/usr/bin/env bash set -eu DOCKER_IMAGE=${DOCKER_IMAGE:-'kohkimakimoto/golang:centos7'} GOTEST_FLAGS=${GOTEST_FLAGS:--cover -timeout=360s} repo_dir=$(cd $(dirname $0); pwd) docker run \ --env GOTEST_FLAGS="${GOTEST_FLAGS}" \ -v $repo_dir:/build/src/github.com/username/repo \ -w /build/src/github.com/username/repo \ --rm \ ${DOCKER_IMAGE} \ bash ./test_run.sh
goコマンドなど、テストに必要な環境は全てDockerイメージとして用意しておきます。あとはリポジトリのルートにいる状態で./test.sh
を実行すれば、テストが実行されます。TravisCIのようなCIサーバはDockerに対応しているので、同様に./test.sh
を実行するだけで、ローカル環境と同じようにテストが実行できます。テストコード側で環境の違いを意識する必要はなくなります。
ところで、しばらくこの方式でやっていたところ、以下のような課題が浮き彫りになってきました。
- 新しいプロジェクトごとにシェルスクリプトをコピペ、修正して使いまわしている。
- これらのスクリプトはだいたい似たようなコードになりがちだが、利用するDockerイメージや
docker run
のオプションなどが微妙にちがう。 - テストやビルドなど個々のタスクごとに「実際のタスクを実行するスクリプト」と「それをDockerコンテナで実行するスクリプト」の2つのファイルを作る必要があり、数が増えるとファイルがごちゃごちゃしてきた。
ベタに書いたシェルスクリプトによる実装なので、プロジェクトが増えると、共通化などができずコードが冗長になりがちでした。そこで、大雑把に処理を整理してみると
などが共通な処理であったので、これらをまとめて、いい感じにDockerコンテナを起動してその中でスクリプトを実行するコマンドラインツールを作りました。
Goで実装したシングルバイナリなので、Githubのリリースページからバイナリをダウンロードして、パスの通ったディレクトリに配置すればすぐに使えます。
使い方
まずは単純に
$ buildsh
を実行してみます。これだけで、デフォルトでDockerイメージkohkimakimoto/buildsh:latest
(2Gくらいあります)をダウンロードして、カレントディレクトリをコンテナ内の/build
にマウントした状態でコンテナを起動します。そのままbashでログインした状態になるので、たとえばPHPのテストだったら
$ php phpunit
などを実行すればテストができます。PHPやPython,nodeなど主なLLのランタイムを入れてあるので、ホストマシンの環境に関係なくすぐにテストやビルドができます。作業が終わったら
$ exit
すれば、ホストマシンにもどってコンテナが破棄されます。特定の環境でちょっとしたことを動作確認したい場合などに便利に使えます。
そしてテストやビルドのシェルスクリプトを実行させたい場合は
$ buildsh test.sh
のようにスクリプトファイルを指定して実行すれば、そのスクリプトがDockerコンテナ内で実行されます。これで用意するスクリプトはテストを実行する部分のみでよくなり、「それをDockerコンテナで実行するスクリプト」を書く必要がなくなりました。
設定ファイル
使用するDockerイメージを変更したい場合などは、設定ファイルを利用することができます。.buildsh.yml
をカレントディレクトリに配置してください。以下のような設定ができます。
use_cache: true docker_image: kohkimakimoto/buildsh:latest additional_docker_options: --net=host -v=/var/run/docker.sock:/var/run/docker.sock environment: FOO: bar FOO2: bar2 home_in_container: /build/src/github.com/kohkimakimoto/buildsh
詳細はREADME.mdを参照していただくとして、いくつかピックアップして概要を説明します。
use_cache
use_cache
はtrueにするとカレントディレクトリ配下に.buildsh/cache
ディレクトリを作り、コンテナ内でパスを環境変数BUILDSH_CACHEDIR
に設定します。これはスクリプト実行ごとに破棄されてしまうコンテナ内のデータを保存するときに使うことができます。たとえばyarn install
を以下のようにすれば、キャッシュを保持できて、次回以降の処理の高速化が望めます。
$ yarn install --cache-folder=$BUILDSH_CACHEDIR/yarn
.gitignore
に.buildsh
を追加するのを忘れずに。。。
docker_image
docker_image
は利用するDockerイメージです。自分の用途に合わせて好きなイメージを使えます。
additional_docker_options
additional_docker_options
は内部で実行しているdocker run
に付け加えるオプションを指定できます。例のように-v=/var/run/docker.sock:/var/run/docker.sock
を利用すればDockerコンテナ内から新しくDockerコンテナを立ち上げることもできたりします。
home_in_container
home_in_container
はコンテナ内でホストのカレントディレクトリがマウントされるパスを変更できます。デフォルトは/build
ですが、例えばGoのテストやビルドをおこなうとき、GOPATHの関係上/build/src/github.com/kohkimakimoto/buildsh
のようにGOの流儀にそったパスに配置したいことがあります。この設定を使うことでそのようなケースに対応できます。
実装について
このツールはつまるところ、テストやビルド目的の使い捨てコンテナである場合docker run
にセットするオプションや引数がおおむね共通化できるので、それをまとめたラッパーコマンドというわけです。
もともとはbashのスクリプトで書いていたこともあって、実装は単純なdocker run
のラッパーコマンドになっているので、メインのコードはbuildsh.goのみです。なのでをこれを見れば何をやっているのか大体わかりますので、細かいことはソースを見たほうが早いかもしれません。
mattn/memoのzsh補完
Golang実装のメモコマンド
Big Sky :: golang でメモ専用コマンド「memo」作った。
GitHub - mattn/memo: 📓 Memo Life For You
が便利だったので、雑にzsh補完を書きました。
_memo_options() { local -a __memo_options __memo_options=( '--help:show help' '-h:show help' '--version:print the version' '-v:print the version' ) _describe -t option "option" __memo_options } _memo_sub_commands() { local -a __memo_sub_commands __memo_sub_commands=( 'new:create memo' 'n:create memo' 'list:list memo' 'l:list memo' 'edit:edit memo' 'e:edit memo' 'delete:delete memo' 'd:delete memo' 'grep:grep memo' 'g:grep memo' 'config:configure' 'c:configure' 'serve:start http server' 's:start http server' 'help:Shows a list of commands or help for one command' 'h:Shows a list of commands or help for one command' ) _describe -t command "command" __memo_sub_commands } _memo_list() { local -a __memo_list PRE_IFS=$IFS IFS=$'\n' __memo_list=($(memo list)) IFS=$PRE_IFS _describe -t memo "memo" __memo_list } _memo () { local state line _arguments \ '1: :->objects' \ '*: :->args' \ && ret=0 case $state in objects) case $line[1] in -*) _memo_options ;; *) _memo_sub_commands ;; esac ;; args) last_arg="${line[${#line[@]}-1]}" case $last_arg in edit|e|delete|d) _memo_list ;; *) ;; esac ;; *) _files ;; esac } compdef _memo memo
~/.zshrc
とかにコピペして使ってください。
※2017-02-10 追記: 本家リポジトリに取り込んでもらいました。https://github.com/mattn/memo/blob/master/misc/completion.zsh
systemd-nspawnで/sys/fs/selinuxがマウントできないので警告される件は無視することにした
ただのメモです。
CentOS7でsystemd-nspawn
の動作を検証してるなか、SELinuxを無効にした状態でコンテナを起動させると/sys/fs/selinux
がマウントできないと警告がでてきました。
# systemd-nspawn -D /var/tmp/mycontainer Spawning container mycontainer on /var/tmp/mycontainer. Press ^] three times within 1s to kill container. Failed to create directory /var/tmp/mycontainer//sys/fs/selinux: No such file or directory Failed to create directory /var/tmp/mycontainer//sys/fs/selinux: No such file or directory -bash-4.2#
/sys/fs/selinux
はSELinuxを無効にすると存在しないディレクトリ。調べたらsystemd-nspawnはHAVE_SELINUX
マクロでこのディレクトリのマウントを制御しています
systemd/nspawn.c at v219 · systemd/systemd · GitHub
そしてログを出力しているところはココ
systemd/nspawn.c at v219 · systemd/systemd · GitHub
ソースを見る限りその後の処理は続行しているし、問題なさそうかな〜と考えていたら、
で、同様の問題の当たっていたヒトがこの警告を消すためにログレベルをLOG_DEBUG
からLOG_WARNING
にさげるPRを送っていてmasterにマージされていました。なので、今後CentOS(systemd)のバージョンが上がれば、この警告は消えるので、現状無視することにした、というお話でした。
CentOS7でサーバを構築する際におこなっている基本設定
以前書いた
CentOS6でサーバを構築する際におこなっている基本設定 - オープンソースこねこね
のCentOS7バージョンです。調査中の内容もあるので、情報は随時更新する予定です。
※ここではサーバのロールにかかわらず行う基本的な作業をまとめています。通常この環境の上にWebサーバ(httpd, nginxなど)やDB(MySQLなど)をインストールすることになります。
※本文中のコマンドは基本的にrootユーザで行っているものとします。一般ユーザを使い必要に応じて都度root権限を使うようにしている方はsudo
をつけるなど、コマンドを読み替えてください。
- デフォルトターゲットの確認
- サービスの起動設定の確認
- ディクスサイズの確認
- ロケールの設定
- タイムゾーンとNTPの設定
- ネットワーク関連の設定
- yumリポジトリ
- bash-completion
- ファイアウォール (firewalld)
- sshd
- ログの管理
- logrotate
- sysctl
デフォルトターゲットの確認
systemctl get-default
で取得。CentoOS6までのデフォルトランレベルに相当します。
# systemctl get-default multi-user.target
multi-user.target
になっていることを確認します。
サービスの起動設定の確認
サービスの管理はsystemdによる管理に刷新されています。
systemctl list-unit-files
でサービスの一覧と状態を取得します。
# systemctl list-unit-files --type service --no-pager UNIT FILE STATE arp-ethers.service disabled auditd.service enabled auth-rpcgss-module.service static autovt@.service disabled blk-availability.service disabled brandbot.service static chrony-dnssrv@.service static
STATEの意味は以下の通り。
不要と思われるサービスはサーバリソースの無駄使いになるので、以下のコマンドで停止設定にしておきます。
# systemctl disable nginx.service # systemctl stop nginx.service
OSの起動時に実行させたいサービスは
# systemctl enable nginx.service # systemctl start nginx.service
としておきます。
ディクスサイズの確認
# df -h
サーバスペックにあったディクスサイズになっていることや、パーティションを確認します。
ロケールの設定
現在のロケールの設定を確認します。
# localectl status
利用可能なロケールをlocalectl list-locales
を調べ、
# localectl list-locales --no-pager
localectl set-locale
で変更。
# localectl set-locale LANG=ja_JP.utf8
ロケールを日本語にしたとき、manページを日本語にするために
# yum install man-pages-ja
をインストールします。
タイムゾーンとNTPの設定
現在のタイムゾーンを確認します
# timedatectl status
利用可能なタイムゾーンをtimedatectl list-timezones
で調べます
# timedatectl list-timezones --no-pager
timedatectl set-timezone
で変更。
# timedatectl set-timezone Asia/Tokyo
RTC in local TZ: yes
の設定になっていると警告がでるので以下を設定する
# timedatectl set-local-rtc 0
CentOS7では時刻同期サービスが2つあって従来のntpd
と新しいchronyd
がある。最小構成でOSインストールした場合は
chronyd
だけがインストールされている状態になっているはず。それぞれ設定ファイルは
/etc/chrony.conf
または/etc/ntp.conf
です。設定ファイルのフォーマットはほとんど同じなので
server 0.centos.pool.ntp.org iburst
のような、時刻問い合わせ先サーバの設定を確認します。
# systemctl start ntpd.service or # systemctl start chronyd.service
でサービスを起動します。
最後にtimedatectl
でntpによる時刻合わせを有効化します。
# timedatectl set-ntp yes
ネットワーク関連の設定
CentOS7ではネットワーク周りの管理がNetworkManagerを使った方式に変更されています。
NetworkManagerのコマンドラインインターフェースであるnmcli
を使って設定するのが標準の方法ですが、
ひとまず従来CentOS6の方法でできることは、それを踏襲してます(非推奨の方法だと思うので、のちのち更新予定です)。
まず、従来のifconfigなどがデフォルトでは提供されていないのでnet-tools
パッケージをインストールします。
# yum install net-tools
ホスト名
従来/etc/sysconfig/network
に記載していたホスト名はCentOS7では/etc/hostname
に記述します。
ネットワーク・インターフェースの確認
CentOS6のときと同様に/etc/sysconfig/network-scripts
配下のifcfg-xxx
を確認します。
設定を変更したら、
systemctl restart network
で反映させます。
IPアドレスの確認
# ifconfig
IPアドレスの設定が、設定通りか確認します。
ネットワークの疎通確認
# ping yahoo.co.jp
pingが外に向けて通るかを確認します。0% packet lossとなればOK。
# traceroute yahoo.co.jp
外につなぎに行く際にどのようなIPを経由するかを確認。ネットワーク管理者ではないので、ざっと結果を眺めるだけです。
yumリポジトリ
CentOS6のときと同様。epelとremiは(個人的に)必須なのでインストールします。epelは直接yumからインストールできます。
# yum install epel-release # yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
その他、設定ファイルなどはCentOS6のときと同様。
bash-completion
CentOS6のときと同様。素のbashのままだとzshになれた補完脳にはツライので、bash-completionを入れます。
# yum install bash-completion
インストールするだけで、ある程度補完が効くようになります。カスタマイズは特にしていません。
ファイアウォール (firewalld)
ファイアウォールはiptablesからfirewalldに変わりました。 firewalldはiptablesをバックエンドにしたファイアウォール管理のフロントエンド的なもので、実は内部的にはiptablesが依然使われています。とはいえ、設定に関してはやることがガラっと変わっています。
設定のための覚書
firewalldにはゾーンという概念があり、サービスやポートへの接続許可、拒否などの設定をまとめた単位。ゾーンはデフォルトで
- block
- dmz
- drop
- external
- home
- internal
- public
- trusted
- work
があります。ファイアウォールはこのゾーンをNICに割り当てることで、有効化され、機能します。
デフォルトではpublic
ゾーンが、有効化、割り当てされています。
# firewall-cmd --list-all
で確認できます。ゾーンについては
# firewall-cmd --list-all-zone
で一覧がでます。
デフォルトで有効になっているpublic
ゾーンは、明示的に許可した通信しか受け入れないようになっているので、基本的にこのゾーンに接続許可するポートやサービスの設定をしておけば、普通のファイアウォールの用途としては要件を満たせそうです。設定はfirewall-cmd
を実行することで行います。
設定
いくつか典型的な設定パターンをメモしておきます。
特定の接続先(この例では192.168.0.1/24)からのみサービスへの接続(この例ではSSH)を許可する場合:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.0.1/24" service name="ssh" accept' --permanent
サービスの定義は/usr/lib/firewalld/services/
配下にあるxmlファイルを読む。ポート番号などがここに定義されています。
特定の接続先(この例では192.168.0.1/24)からのみポート8000の接続を許可する場合:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.0.1/24" port port="8000" protocol="tcp" accept' --permanent
ポート80の接続を許可する場合:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" port port="80" protocol="tcp" accept' --permanent
ちなみに上記のポートを単純に開放するだけなら
# firewall-cmd --zone=public --add-port=80/tcp --permanent
でも良さそう。個人的に設定の書き方を統一しておきたいので基本的に--add-rich-rule
を使っています。
設定を変更したら
# firewall-cmd --reload
で反映させます。その後確認のために
# firewall-cmd --list-all
でゾーンの設定を表示し、内容をチェックします。
sshd
CentOS6のときと同様。ポート番号を変えて、鍵認証オンリーにします。以下、編集および確認箇所のみを記載します。
/etc/ssh/sshd_config
# 22以外に変えます Port 2222 # rootログインは禁止 PermitRootLogin no # パスワード認証は禁止 PasswordAuthentication no
再起動して設定を反映します。
# systemctl restart sshd
ログの管理
syslogに代わる新しいログデーモンとしてjournaldが提供されています。systemdのサービスとして起動されたプログラムの標準出力、標準エラー出力は自動的にjournaldへと送られてログ管理の対象になります。ログはバイナリデータで保存され、専用のjournalctl
コマンドを使って検索、表示させるという操作になります。
ログの保存場所はデフォルトで/var/run/log/journal
。これは一時領域なので再起動したら消えてしまうため、/var/log/journal
に変更する。
# mkdir /var/log/journal # systemctl restart systemd-journald
上記のように/var/log/journal
を作成して、journaldを再起動すればOK。
ログの容量の最大サイズはファイルシステムの10%まで。変更するには/etc/systemd/journald.conf
ないで
SystemMaxUse=500M RuntimeMaxUse=500M
のようにサイズ指定すればよいです。
参考:http://www.server-memo.net/centos-settings/journald/journald.html
logrotate
ログのローテート設定です。journaldにではなく、サービスが直接ファイルになどに出力したログファイルをローテートします。
CentOS6のときと同様です。ログが無尽蔵に大きくなってディクスサイズを圧迫しないように設定、確認します。 初期設定時の他にhttpdなどのデーモンやログを出力するアプリケーションを追加した時にも目を通します。
/etc/logrotate.d/以下にログの対象ごとに設定ファイルがあるのでそれを確認します。例えばnginxは以下のようになっていたりします。
/etc/logrotate.d/nginx
/var/log/nginx/*log { create 0644 nginx nginx daily rotate 10 missingok notifempty compress sharedscripts postrotate /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true endscript }
実際の設定はログのサイズや保存期間の要件などによって異なるので、それを考慮し設定します。
sysctl
CentOS6と同様、カーネルパラメータの設定です。CentOS6のときは/etc/sysctl.conf
を編集してましたが/etc/sysctl.d/
配下にxxx..conf
ファイルを配置しても設定できるので、そうしてます。(実はCentOS6のときからできたっぽいですが。参考:http://qiita.com/ngyuki/items/002a4a153ac6d8075bdb)
/etc/sysctl.d/override.conf
net.nf_conntrack_max = 1000000 net.netfilter.nf_conntrack_max = 1000000 net.core.somaxconn = 1024 vm.overcommit_memory = 1
設定の内容はCentOS6でサーバを構築する際におこなっている基本設定 - オープンソースこねこねを参照。設定値の反映は以下のコマンドを実行します。
# sysctl --system
参考: http://tsunokawa.hatenablog.com/entry/2015/09/02/175619
以下のコマンドで確認。
# sysctl -a