curlでhost指定・名前解決して実行

ここ何ヶ月か、某社から「TLS1.1以下サポート終了のためテスト環境にてご確認お願いします」ってことでIPとテスト環境のドメインが送られてくることがまれによくある。。
弊社の開発サーバーではインフラチームしかsudo権限がないのでhostsファイルはいじれないけどちょっとした疎通確認のため申請出してわざわざhosts設定してもらうのは面倒なのでやらない。

そんなときにググってよく見るのはヘッダでhost指定してやるやり方

$ curl -H 'Host:example.com' http://192.168.33.10/

PHPだと

$curl = curl_init("http://192.168.33.10/");
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Host: exsample.com']);

こんな感じ。

ただ、件のテスト環境ではヘッダでhost指定するやり方では動かなかったので別の方法で。 ということで見つけたのが--resolveオプション。 リクエストヘッダにHost名持たせて指定のIPアクセスするのではなくhostsファイルいじったのと同じように名前解決させるイメージでいいのかな。

$ curl --resolve example.com:80:192.168.33.10 http://example.com/

PHPだと

curl_setopt($ch, CURLOPT_RESOLVE, array("example.com:80:192.168.33.10"));

これで疎通確認できました。

まとめると
DNS登録されてないドメイン宛にリクエストする場合、

  • ヘッダでhost指定する方法
    • curl -H 'Host:{$domain}' http://{$ip}/
  • --resolveオプションで名前解決させる方法
    • curl --resolve {$domain}:80:{$ip} http://{$domain}/

2つのやり方がありますよと。

deployer使ってみた忘備録

deployerを使った時に困ったことなどメモ程度に。

deployer.org

 

前提条件

2017年8月時点で調べた事
v5.1.3の話 (ubuntu16.04のcomposerのデフォルトだったので)
 

調べたこ

  • デプロイサーバーからソースコードをセットアップして本番サーバーにrsyncしたい
  • 本番とステージングが同じサーバーに同居させたい  

デプロイサーバーからソースコードをセットアップして本番サーバーにrsyncしたい

deployerにはデプロイ時の基本的な処理がrecipeとして用意されているが、それらの処理はデプロイ先サーバーで実行されるようになっている。

デプロイの際、最新のソースコードをクローンしてきたあと、必要に応じてgulpタスクとcomposer installの実行をした上で複数サーバーに設置したく、それぞれのサーバーでわざわざ別々に同じことを実行させる必要もなかったのでデプロイサーバー上でソースをセットアップした上でデプロイ先に送るようにしたかった。

deployer用意されているrecipeではrun()で様々な処理を用意しているが、これはすでに書いたとおりデプロイ先サーバーで実行するようのファンクションであった。

ではローカル上で処理を行うには、ということでdeployerにはrunLocally()と言うものも用意されている。ただしrunLocally()ではデプロイサーバーからデプロイ先それぞれのサーバーに対して実行するファンクションであり、これでcomposer installなどしようとすればローカル上でデプロイ対象サーバーの数と同じ回数composer installすることになる。当初deployerでの処理を作るにあたりこれを利用していたが、開発用に用意していたデプロイ先サーバーは1台だったのに対し、本番サーバーは複数台構成だったため、いざ本番環境で実行しようとした際に思うように行かなかった。

というわけで、このような場合にはrunLocally()は使えず、

task('build', function () {

...

})->local();

Deployer — Tasks

taskの最後にアローでlocal()とつなげばデプロイ元サーバー上で一度だけ実行される。(run、runLocally共に)
これで解決。

rsyncの処理は公式サイトに載っているサードパーティrecipeを使えばOK。
Deployer — Deployer Recipes
※deployerは更新時に下位互換を結構切ってるようなので使うバージョンの注意が必要かも

本番とステージングが同じサーバーに同居してる場合

deproyerのデプロイ先ホストとパスの指定は基本的には以下の通り。

host('domain.com')
    ->stage('production')
    ->roles('app')
    ->set('deploy_path', '~/app');

  Deployer — Hosts

これで本番とステージングが同じサーバーに同居させようとすると

host('domain.com')
    ->stage('production')
    ->roles('app')
    ->set('deploy_path', '~/app/production');


host('domain.com')
    ->stage('staging')
    ->roles('app')
    ->set('deploy_path', '~/app/staging');

例えばこんな感じに設定すると実行時にエラーになる。
なんかバグらしい。。
Fix bug with parallel deploy to same host by antonmedv · Pull Request #1271 · deployphp/deployer · GitHub

host('production')
    ->hostname('domain.com')
    ->stage('production')
    ->roles('app')
    ->set('deploy_path', '~/app/production');


host('staging')
    ->hostname('domain.com')
    ->stage('staging')
    ->roles('app')
    ->set('deploy_path', '~/app/staging');

hostには適当な名前をつけ、hostnameでデプロイ先のホストを指定することで解決。
無事デプロイできた。

おしまい。

Azure LBを通してDigest認証がうまくいかなかった時の対応

お仕事でサーバーの設定をしたので忘備録的な話。

Azure上の2台構成のWebサーバーに対して設定していたDigest認証がうまくいかなかったと言われ。。

[Wed Oct 05 19:27:09.166831 2016] [auth_digest:error] [pid 32052] [client 192.168.45.174:60598] AH01776: invalid nonce aixFnRs+BQA=3ec1f113a98be1e2eb27e235bebc617fafcd070b received - hash is not 74d2414f23684029f9fd73ae2c0baabd8851d8f8
こういうエラーが出てしまいまして
https://curecode.jp/tech/amazon-elb-and-digest-auth-problem/ ↑はAmazonのケースですが
ロードバランサー経由で複数台のウェブサーバを使っていることが理由と推測しているのですが、
Azureのサーバで↑に相当するような、設定は無いでしょうか?

ふむ。そもそもDigest認証ってなんぞと。

Digest認証 - Wikipedia

なるほど。要するにLB通すことで最初に認証したサーバーと違うサーバーにアクセスしたらDigest認証はうまくいかないと。
だからLBにそういう設定をしないといけないと。
(そういう要件聞いてないってのは置いといて)

Amazon ELB と Digest 認証の組み合わせがうまくいかない | キュア子の開発ブログ

頂いたリンクによるとAmazonのELBではcookieの設定変えて接続先を維持すればおkと。

AzureのLBではcookie使ってんのかは知らんけど、 LBの先の接続先サーバーを維持するには
ロードバランサーの設定から「負荷分散規則」→「セッション永続化」の設定で
「クライアントIP」か「クライアントIPとプロトコル」か選択すればおk。

これでDigest認証の問題も解決

sudoでなれるユーザーの制限(Not rootになれるユーザーの制限)

お仕事でサーバーの設定をしたときにググって知りたいことがあまり引っかからなかったので忘備録的な。。

デプロイサーバーの設定で一部の開発者にデプロイ権限を与えることに。サービスごとにデプロイサーバーにユーザーを作り、そのユーザーからデプロイを行う。

ただしsudoのすべての権限を与えるのでなく、あくまでデプロイユーザーになれる権限だけを。

「sudo なれるユーザー 制限」とか検索してもrootになれるユーザーを制限する方法とかばっか出てくるので。。。

sudoの設定は/etc/sudoersを編集するか/etc/sudoers.s/以下にファイル作るか。 書式はこんな感じ

root   ALL=(ALL)   ALL

意味としては

root ALL (ALL) ALL
ユーザー ホスト 権限 コマンド

この書式の意味に関しては他にいくらでも書いてある記事があるのでこれ以上は省略

今回はこのsudoerの設定を使って以下の手順でデプロイの権限を制限した

  1. まずデプロイを行うユーザーをdeployとして作成
  2. deployグループを作りデプロイ権限を与えるユーザーをdeployグループに追加
  3. deployグループのユーザーにdeployユーザーになれるよう設定

ユーザー作成とグループの作成・追加は省略。 sudoerの設定は以下の通り

%deploy   ALL=(root)  /bin/su - deploy
%deploy ALL (root) /bin/su - deploy
deployグループのユーザーに rootユーザー権限で /bin/su - deployを実行できる

これでdeployグループのユーザには sudo su - deploy ができるようになった。
ちなみに(root)の権限の部分、deployユーザーになるんだから(deploy)とかでいけそうとか思えるけど、やってみてできなかったので注意。

鍵交換でのssh接続

sshログインの鍵交換のためのスクリプト書いて使ってました。

#!/bin/sh

KEY_TYPE='rsa'
KEY_NAME="${HOME}/.ssh/id_rsa"
AUTHORIZED_KEY='.ssh/authorized_keys'
TMP=`date +%s.pub`

echo "host:"
read HOST_NAME

echo "host user name:"
read USER_NAME

## 鍵が無ければ作成する
[ -s $KEY_NAME ] || ssh-keygen -t ${KEY_TYPE} -P ''

## 公開鍵をリモートホストにコピー
echo "scp ${KEY_NAME}.pub ${USER_NAME}@${HOST_NAME}:./${TMP}"
scp ${KEY_NAME}.pub ${USER_NAME}@${HOST_NAME}:./${TMP}
echo "ssh ${USER_NAME}@${HOST_NAME} \"cat ./${TMP} >> ${AUTHORIZED_KEY} && chmod 644 ${AUTHORIZED_KEY} && rm ./${TMP}\""
ssh ${USER_NAME}@${HOST_NAME} "cat ./${TMP} >> ${AUTHORIZED_KEY} && chmod 644 ${AUTHORIZED_KEY} && rm ./${TMP}"

exit 0

が、最近ansibleについて調べていた時に初めて知りました。

linux.die.net

brew install ssh-copy-id

からの

ssh-copy-id [-i ~/.ssh/id_rsa.pub] <username>@<host>

これだけですみました

tmuxで複数サーバーの同時操作

本番環境同様にサーバー複数台でLB通してアクセスの来るステージ環境でサービスのある挙動のログを見たい時があった。

tailfでログ流しながら確認したいけどどのサーバーに来るかわからんと。

そのため全台確認するために同時操作がしたい。

とりあえず「tmux 複数サーバ」で検索して一番上に来たこの記事を参考にログインユーザー指定のオプションと使い方を追加したシェルスクリプトをつくってみた。

#!/bin/bash

usage(){
    echo './multi_ssh.sh [-u username] host ...'
}

while getopts "hu:" opts
do
  case $opts in
    h)
      usage
      exit
      ;;
    u)
      usr=$OPTARG 
      ;;
  esac
  shift
  shift
done

if [ -z "$usr" ];then
    usr=`whoami`
fi

if [ -n "$SESSION_NAME" ];then
    session=$SESSION_NAME
else
    session=multi-ssh-`date +%s`
fi
window=multi-ssh

### tmuxのセッションを作成
tmux new-session -d -n $window -s $session

### 各ホストにsshログイン
# 最初の1台はsshするだけ
tmux send-keys "ssh ${usr}@${1}" C-m
shift

# 残りはpaneを作成してからssh
for i in $*;do
    tmux split-window
    tmux select-layout tiled
    tmux send-keys "ssh ${usr}@${i}" C-m
done

### 最初のpaneを選択状態にする
tmux select-pane -t 0

### paneの同期モードを設定
tmux set-window-option synchronize-panes on

### セッションにアタッチ
tmux attach-session -t $session

おっしゃ、やりたいことはできた。

まあ、こんなみんな考えそうなことは誰かしらやってるわけで、見つけてしまいましたよ…

tmux-csshで複数サーバに対するカジュアルなオペレーション

brew installするだけのかんたんなお仕事でした。 車輪の再発明ってやつでしたかね。。。

Android端末を開発用サーバーにしてみる② ~SSH接続編~

にわかガジェオタとして私それなりにスマホ端末を所持しているわけですが、なかなか使い道がない端末もあるということで今回、自宅サーバーとして活用していこうと。

今回はSSHAndroid端末に接続できるように。

利用するのはSSHDroidというアプリ。

起動すればSSHコマンドでAndroid端末に接続できるようになります。

f:id:iettty:20151026235422p:plain

 

 

ターミナルからSSHコマンドで接続。

f:id:iettty:20151026235444p:plain

 

デフォルトパスワードはadminになっているので、アプリの設定から変えておきましょう。

f:id:iettty:20151026235500p:plain

接続出来ました!!

PATHは/system下だけでなくこのアプリのディレクトリ下にも通っているので、このアプリによって追加されたコマンドも使えるようになっています。 f:id:iettty:20151026235539p:plain

このアプリによって使えるコマンドはこのとおりです。f:id:iettty:20151026235556p:plain

 

ssh root@~で接続してますがユーザーはこのアプリユーザーとしてのログインになります。

f:id:iettty:20151026235610p:plain

root化されているAndroid端末であれば、アプリ側の設定を変えればrootユーザーとしてSSH接続ができるようになります。アプリが終了しないようステータスバーへの常駐する設定や端末起動時の自動起動SSH接続のポート番号やログインパスワードなどの設定変更もここで行えます。

f:id:iettty:20151026235656p:plain

 

有料版にアップグレードすれば公開鍵認証での接続などの機能も使えるようになるようです。

f:id:iettty:20151026235709p:plain

以上、今回はこのあたりで〜