20200403のLinuxに関する記事は5件です。

さすがに無いと思うが、古いLinuxを使っててTLS1.2に対応できない対応方法

Chromeが81にバージョンアップされると、TLS1.0や1.1を使っていると警告ブロックになるとのうわさがあるため、弊社のサーバは問題無いが困っている人がもしかしたらいるかも!?という前提で簡単にまとめておきます。
OpenSSLとmod_sslだけソースからコンパイルしたものを使う方法もあるようだけど、OPenSSLのバージョンが新しくならなかったので速攻であきらめました。

大まかな手順

ApacheとOpenSSLをソースからコンパイルする。移行をできるだけ簡単にしたいので、Apacheの設定ファイルは基本的にそのまま使用する。

サーバ環境

Debian5(lenny)
Apache2.2.9
OpenSSL0.9.8

手順

OpenSSL

まずはOpenSSLをDLしてコンパイル。今回は「openssl-1.0.1q.tar.gz」を選択。こっちは簡単。
https://www.openssl.org/source/old/1.0.1/

./config --prefix=/usr/local/ssl shared zlib
make
make install

続いてldconfigで共有ライブラリを設定。下記のファイルを新規で作成したパスを追加。

/etc/ld.so.conf.d/openssl.conf
/usr/local/ssl/lib

キャッシュファイル更新後、grepで確認。

ldconfig
ldconfig -p | grep -i libssl
        libssl.so.1.0.0 (libc6) => /usr/local/ssl/lib/libssl.so.1.0.0
        libssl.so.0.9.8 (libc6, hwcap: 0x0008000000008000) => /usr/lib/i686/cmov/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6, hwcap: 0x0004000000000000) => /usr/lib/i586/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6, hwcap: 0x0002000000000000) => /usr/lib/i486/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6) => /usr/lib/libssl.so.0.9.8
        libssl.so (libc6) => /usr/local/ssl/lib/libssl.so
        libssl.so (libc6) => /usr/lib/libssl.so

libssl.soが二つあるけど、気にしないようにした。

Apache

下記サイトより、同バージョンもしくは、ちょっと新しいバージョンをDLして展開。今回は「httpd-2.2.10.tar.gz」を使用。
https://archive.apache.org/dist/httpd/

./configure --enable-so --enable-ssl --with-ssl=/usr/local/ssl/ --with-included-apr --with-included-apr-util --enable-mods-shared="all ssl"
make
ここでエラー
 ssl_engine_init.c:576: error: ‘STACK’ undeclared (first use in this function)
 ssl_engine_init.c:576: error: (Each undeclared identifier is reported only once

新しいOpenSSLでは「STACK」が「_STACK」に変更されているので、下記2ファイルを修正。「httpd-2.2.16」以降では対応できている可能性あり。

httpd-2.2.10/modules/ssl/modules/ssl/ssl_engine_init.c
httpd-2.2.10/modules/ssl/modules/ssl/ssl_util_ssl.c

そしてコンパイル。

make
make install

設定ファイルを修正。追加だけ書いておきます。

/usr/local/apache2/conf/httpd.conf
Listen 443

LoadModule log_config_module modules/mod_log_config.so
LoadModule ssl_module modules/mod_ssl.so
※mod_sslはここで読むのがポイント。パッケージconfのパスを変更してもOpenSSLが新しくならない。
※他のLoadModuleはコメントアウト

//パッケージの設定ファイル
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf

NameVirtualHost *:80
NameVirtualHost *:443

//パッケージの設定ファイル
Include /etc/apache2/sites-enabled/

最後に

パッケージApacheを停止してソースバージョンを起動。下記コマンドなどで確認できます。

openssl s_client -connect ******.com:443
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

さすがに無いと思うが、古いLinuxを使っててTLS1.2に対応できない対処方法

Chromeが81にバージョンアップされると、TLS1.0や1.1を使っていると警告ブロックになるとのうわさがあるため、弊社のサーバは問題無いけど、困っている人がもしかしたらいるかも!?という前提で簡単にまとめておきます。
OpenSSLとmod_sslだけソースからコンパイルしたものを使う方法もあるようだけど、OPenSSLのバージョンが新しくならなかったので速攻であきらめました。

大まかな手順

ApacheとOpenSSLをソースからコンパイルする。移行をできるだけ簡単にしたいので、Apacheの設定ファイルは基本的にそのまま使用する。

サーバ環境

Debian5(lenny)
Apache2.2.9
OpenSSL0.9.8

手順

OpenSSL

まずはOpenSSLをDLしてコンパイル。今回は「openssl-1.0.1q.tar.gz」を選択。こっちは簡単。
https://www.openssl.org/source/old/1.0.1/

./config --prefix=/usr/local/ssl shared zlib
make
make install

続いてldconfigで共有ライブラリを設定。下記のファイルを新規で作成したパスを追加。

/etc/ld.so.conf.d/openssl.conf
/usr/local/ssl/lib

キャッシュファイル更新後、grepで確認。

ldconfig
ldconfig -p | grep -i libssl
        libssl.so.1.0.0 (libc6) => /usr/local/ssl/lib/libssl.so.1.0.0
        libssl.so.0.9.8 (libc6, hwcap: 0x0008000000008000) => /usr/lib/i686/cmov/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6, hwcap: 0x0004000000000000) => /usr/lib/i586/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6, hwcap: 0x0002000000000000) => /usr/lib/i486/libssl.so.0.9.8
        libssl.so.0.9.8 (libc6) => /usr/lib/libssl.so.0.9.8
        libssl.so (libc6) => /usr/local/ssl/lib/libssl.so
        libssl.so (libc6) => /usr/lib/libssl.so

libssl.soが二つあるけど、気にしないようにした。

Apache

下記サイトより、同バージョンもしくは、ちょっと新しいバージョンをDLして展開。今回は「httpd-2.2.10.tar.gz」を使用。
https://archive.apache.org/dist/httpd/

./configure --enable-so --enable-ssl --with-ssl=/usr/local/ssl/ --with-included-apr --with-included-apr-util --enable-mods-shared="all ssl"
make
ここでエラー
 ssl_engine_init.c:576: error: ‘STACK’ undeclared (first use in this function)
 ssl_engine_init.c:576: error: (Each undeclared identifier is reported only once

新しいOpenSSLでは「STACK」が「_STACK」に変更されているので、下記2ファイルを修正。「httpd-2.2.16」以降では対応できている可能性あり。

httpd-2.2.10/modules/ssl/modules/ssl/ssl_engine_init.c
httpd-2.2.10/modules/ssl/modules/ssl/ssl_util_ssl.c

そしてコンパイル。

make
make install

設定ファイルを修正。追加だけ書いておきます。

/usr/local/apache2/conf/httpd.conf
Listen 443

LoadModule log_config_module modules/mod_log_config.so
LoadModule ssl_module modules/mod_ssl.so
※mod_sslはここで読むのがポイント。パッケージconfのパスを変更してもOpenSSLが新しくならない。
※他のLoadModuleはコメントアウト

//パッケージの設定ファイル
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf

NameVirtualHost *:80
NameVirtualHost *:443

//パッケージの設定ファイル
Include /etc/apache2/sites-enabled/

最後に

パッケージApacheを停止してソースバージョンを起動。下記コマンドなどで確認できます。

openssl s_client -connect ******.com:443
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SCPで踏み台の向こうにあるホストへ多段接続してファイルを一発で送る方法

  • 環境
    • 接続元
      • CentOS Linux release 7.6.1810 (Core)
      • OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
    • 踏み台ホスト : Amazon Linux release 2 (Karoo)
    • 置き場ホスト : Red Hat Enterprise Linux Server release 5.11 (Tikanga)

やりたいこと : 踏み台の向こうにある置き場ホストに一発でファイルを転送したい

ファイルを接続元から踏み台において、踏み台から置き場において・・・というのが面倒くさい。
2020-04-03 17.18.36.jpg

SCPでProxyCommandを使って多段接続すればいい

フォーマット
# -r : ディレクトリ内を再帰的にコピーします。
# -o : 設定ファイル(ssh_config)で使われている形式のオプションを ssh に渡す
# -W : %hと%pを本来の接続先とそのポートへ置換する
$ scp -i {踏み台鍵} -r -o ProxyCommand='ssh -i {置き場鍵} -W %h:%p {踏み台ユーザ}@{踏み台アドレス}' {自分ディレクトリパス} {置き場ユーザ}@{置き場アドレス}:{置き場ディレクトリパス}

やってみた

SSHでも同じようにProxyCommandを使って多段接続すれば、踏み台の向こうにあるホストへ一発でログインできる。

# SCPでファイルを転送する
$ scp -i ~/.ssh/fumidai.pem -r -o ProxyCommand='ssh -i ~/.ssh/okiba.pem ponsuke@12.134.567.890 -W %h:%p' /home/ponsuke/HOGE.war ponsuke@10.0.2.1:/tmp/.
Enter passphrase for key '/home/ponsuke/.ssh/fumidai.pem':
Enter passphrase for key '/home/ponsuke/.ssh/okiba.pem':
HOGE.war                                                                                                                   100%   38MB  44.2MB/s   00:00
Killed by signal 1.

# SSH接続しておいたファイルを確認しに行ってみる
$ ssh -i ~/.ssh/fumidai.pem -o ProxyCommand='ssh -i ~/.ssh/ponsuke.pem ponsuke@12.134.567.890 -W %h:%p' ponsuke@10.0.2.1
Enter passphrase for key '/home/ponsuke/.ssh/fumidai.pem':
Enter passphrase for key '/home/ponsuke/.ssh/okiba.pem':
Last login: Thu Apr  2 14:49:44 2020 from 10.0.3.182
# ちゃんと送られていた
$ ls /tmp/
HOGE.war
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

curlコマンドでちょこっとHTTPリクエストを試すだけの記事

はじめに

こんにちは!お久しぶりです。
「実行されるとアプリサーバーにJSONを送るだけのバッチ」を作りたい人です1

先輩に実装方法を聞いたら「そんなんcurl一択やんけ」と言われたので、curlコマンドを調べて使ってバッチを作成しました!

その時に得た知識をまとめていきたいと思います。

この記事では、以下の順番でcurlの基礎をご紹介していきます。

  • curlコマンドって何?
  • curlの基本の使い方
  • どんな動作するのか、さくっと試したい!(試せますぞ!)
  • curlの後ろにオプションをつけると、いろいろなことができますぞ!

curlコマンドって何?

curlコマンドは、こちらの記事で紹介されているように、様々なプロトコルを使用してデータ転送を行うことができるコマンドです。

HTTPのGETやPOSTはもちろん、HTTPSやFTP, Telnet, SMTP, IMAP, POP3など様々な通信プロトコルをサポートしています。

最近の端末には最初から入っていて、ターミナルですぐにcurlコマンドを使用できる状態だと思いますが、入っていない場合はインストールが必要です

当記事での環境とバージョン

macOS Catalina
curl 7.64.1

$ curl --version
curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2
Release-Date: 2019-03-27
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets

バージョン情報を聞いただけでサポートしてるプロトコルとバージョンの特色も表示してくれるの、優しいですね!

今回はプロトコルの中でもHTTP通信のみ使用していきます!

curlの基本の使い方

curlコマンドの基本形は下記の通りです。

$ curl {URL}

これで、URLのコンテンツをコンソールに表示させることができます。

試しにGoogleをcurlしてみましょう。

$ curl https://www.google.com/

<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="&#19990;…
…中略…
…google.pmc=JSON.parse(pmc);})();</script></body></html>

Googleをcurlで取得すると、このようにひどく長いHTMLが取得できると思います。

Googleのレスポンス、長いし意味分かんないよ!ピンと来ないよ!という方は、阿部寛さんのホームページを参考にしてみてはいかがでしょうか?

$ curl http://abehiroshi.la.coocan.jp/

<html>
<head>
…中略…
<title>阿部寛のホームページ</title>
</head>
  …中略…
  <body></body>
  …中略…
</html>

上述のようなシンプルで美しいHTMLが返ってこれば、上手く行っています!
(titleが文字化けしていても、通信自体はうまく行っているので大丈夫です!阿部寛さんのホームページでF12/option+command+Iを押してみて、内容を見比べてみてください!)

もし下記のようなメッセージが出てくる場合、curlがデフォルトで入っていない可能性があるので、インストールを試してみてください

zsh: command not found: curl

どんな動作するのか、さくっと試したい!(試せますぞ!)

さて、これからcurlコマンドを書いていくのですが、実際にアプリサーバと疎通した時にどういう返事が返ってくるのか、気になりませんか?

さくっと試してみるだけなら、Googleとか有名なサイトを少し見てみれば良いのですが、

「エラーが出たときはどんなものが返ってくるのか?」
「GETばかりしているけれど本当はPOSTしたいんだよね…2

こういう時に、いつまでもまるっと阿部さんに頼りきりではいけませんよね…

そんな時にはhttpbinがおすすめです!

スクリーンショット 2020-03-30 21.46.55.png

こちらは、HTTPリクエストをすると、いろいろなレスポンスを返してくれるWebサイトです。リクエストの書き方が正しいか、きちんとHTTP通信を行えるものなのかをさらりと確認できます!

また、URLを少し変えるだけで、GETやPOSTをそれぞれ行えたり、終了コードを恣意的に400や500にしたりすることもできます。curlに限らず、HTTP/HTTPS通信するコードだけぬるっと試してみたい時におすすめのWebサービスです。

この記事でも、しれっとhttpbinを使用していきます〜

curlの後ろにオプションをつけると、いろいろなことができますぞ!

さて、今まではシンプル・オーソドックス・ビューティフルかつピュアなcurlコマンドで遊んできましたが、実はcurlの後ろにはオプションを設定することができます!

これによってGETやPOSTを使い分けたり、ヘッダーやボディー、レスポンスを詳細に設定したり、エラーメッセージを表示させなかったりと、様々な詳細設定が可能となるのです。

【メソッド変更】curl -X {リクエストメソッド} “URL”

まずは、最もシンプルなリクエストメソッドの変更を試してみましょう。

Googleの例のように、何もオプションをつけないとGETメソッドとなりますが、明示的にリクエストメソッドを指定したい場合は-X {リクエストメソッド} “URL”で変更することができます。

##########
# GETメソッド
# (curl http://httpbin.org/getと同じ結果になる)
##########

$ curl -X GET "http://httpbin.org/get"

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=12345678901234567890"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/get"
}

こちらはPOSTメソッドの例3です。

##########
# POSTメソッド
##########

$ curl -X POST "http://httpbin.org/post" 

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=12345678901234567890"
  }, 
  "json": null, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/post"
}

【ヘッダ変更】curl -H “{パラメータ}”: “{値}”

-H “{パラメータ}”: “{値}” をつけることで、HTTPヘッダを追加することができます。
(ここからはPOSTメソッドで試していきます!)

$ curl -X POST "http://httpbin.org/post" -H "accept: application/json"

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=12345678901234567890"
  }, 
  "json": null, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/post"
}

いかがでしょうか?

さっきのものとじっくり比べると、 “headers”内の “Accept”項目が変化しているのが分かりますね!

先ほどの-Xのみの例では "Accept": "/" だったのに対し、今回の-X -Hでは Accept": "application/json" となっています!

【コンテンツ変更】curl -X POST -d ‘{“パラメータ”}: {“値”}’

今度はいよいよPOSTメソッドでJSONを送ってみます!

HTTPヘッダに"content-type: application/json"を追加し、POSTメソッドに-dオプションを付与することで、POSTメソッドでJSON形式のデータをリクエストすることができます。

$ curl -H "content-type: application/json" -X POST -d'{"asa_gohan":"misosiru", "oyatsu":"karl"}' http://httpbin.org/post

{
  "args": {}, 
  "data": "{\"asa_gohan\":\"misosiru\", \"oyatsu\":\"karl\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "41", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=12345678901234567890"
  }, 
  "json": {
    "asa_gohan": "misosiru", 
    "oyatsu": "karl"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/post"
}

朝ご飯といえば味噌汁、おやつといえばkarlですよね!

【通信詳細出力】curl -v

-vオプションHTTP通信の詳細を出力するためのオプションです。

リクエストヘッダ、レスポンスヘッダとボディが見れるので、デバッグする時に付与すると便利です。

$ curl -v -H "content-type: application/json" -X POST -d'{"asa_gohan":"misosiru", "oyatsu":"karl"}' http://httpbin.org/post

*   Trying xxx.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to httpbin.org (xxx.xxx.xxx.xxx) port xx (xx)
> POST /post HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.64.1
> Accept: */*
> content-type: application/json
> Content-Length: 41
> 
* upload completely sent off: 41 out of 41 bytes
< HTTP/1.1 200 OK
< Date: Mon, 30 Mar 2020 xx:xx:xx GMT
< Content-Type: application/json
< Content-Length: 486
< Connection: keep-alive
< Server: xxxxxxxx/xxxxxxxx
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< 
{
  "args": {}, 
  "data": "{\"asa_gohan\":\"misosiru\", \"oyatsu\":\"karl\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "41", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.64.1", 
    "X-Amzn-Trace-Id": "Root=12345678901234567890"
  }, 
  "json": {
    "asa_gohan": "misosiru", 
    "oyatsu": "karl"
  }, 
  "origin": "xxx.xxx.xxx.xxx", 
  "url": "http://httpbin.org/post"
}
* Connection #0 to host httpbin.org left intact
* Closing connection 0

この最後の行の0は、Linuxコマンドの終了コードです。

Linuxコマンドは正常終了時は0、異常終了時は1~255の正の整数が返ってくるものなのですが、curlはHTTP通信時に400系エラーや500系エラーなどが出ても、終了コードが0になってしまいます。

あたかも成功したかのような顔をするタイプのコマンドです。いけすかないですね。

【終了コード変更】curl -f

エラーになってもしれっと正常終了する、ミス隠蔽マンcurlくんですが、-fオプションを付ければ、異常終了時に終了コード22で終わってくれます!やったー!

httpbinのStatus codesを使用します。

スクリーンショット 2020-03-30 23.25.22.png

まずは-fオプションなしのエラー

##########
# 400
##########
$ curl -X POST "http://httpbin.org/status/400" -H "accept: text/plain"

# 何も出ない…成功したの?失敗したの?(本当は400エラーで失敗している)
# echo $?コマンドで、直前に実行したコマンドの終了コードを表示できます。

$ echo $?
0

ほら…すぐ嘘つくんだから…

しかし、-fを付与してあげると、きちんとエラーを吐いてくれます!

##########
# 400
##########
$ curl -f -X POST "http://httpbin.org/status/400" -H "accept: text/plain"
curl: (22) The requested URL returned error: 400 BAD REQUEST

# やったー!分かりやすい!
# echo $?コマンドで一応確認しておきます。

$ echo $?
22

ヤッターーーー!!!!

404でも500でも、curlのエラーコードとHTTPエラーコードが表示されるので、とっても分かりやすいです!

$ curl -f -X POST "http://httpbin.org/status/404" -H "accept: text/plain"                                                       
curl: (22) The requested URL returned error: 404 NOT FOUND


$ curl -f -X POST "http://httpbin.org/status/500" -H "accept: text/plain"
curl: (22) The requested URL returned error: 500 INTERNAL SERVER ERROR

ただ、curl -fのみではフェールセーフではなく、401や407エラーなど認証系エラーが無視される可能性があるという公式ドキュメントの記述もあります。

そのためcurl -sSを追加してエラー時のみエラーメッセージを表示する方法もあるそうです!

おわりに

curl難しい…!特に終了コードの概念はなかったので、新しいことだらけでびっくりしてました!

また、誤認等ございましたら、そっと教えていただけますと幸いです…!>< よろしくお願いいたします。

ちなみに「実行されるとアプリサーバーにJSONを送るだけのバッチ」は無事に完成したので、前回の記事でご紹介いただいたラーメン屋さんで一杯やろうかと思います!

いっぱいコメントありがとうございました!5億杯食べてきますね〜


  1. 当記事は下記記事の続きですが、「Linuxとかシェルって何?」を知っていればこの記事からでも読めます!【黒い画面恐怖症向け】Linuxとかシェルとかざっくり知りたいのでゆるく図解した 

  2. GETとPOSTの違いはこちらのQiita記事が分かりやすいです! 

  3. httpbinでは、デバッグ等に便利なようレスポンスにorigin等出してくれちゃうのですが、個人情報もあるため記事では伏せています! 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vimで読み取り専用ファイルを編集、保存する

EC2上でreadonlyファイルを編集しようとした時に一瞬詰まったので備忘録を。
やり方は2通りある。

方法1:ファイルを開く段階でsudoコマンドを付ける

一番シンプルで一番簡単な方法。

ターミナル
$ sudo vim 編集したいファイルを選択

これならvimで編集後、普段通り:wqで保存が可能。

方法2:readonlyのまま編集したファイルを強制保存

これが一番よくあるパターンだと思う。てか私がなったからこれを書いているわけだが。
編集した後にそういやsudoで実行してない!となっても焦らず下記コマンドを叩けば良い。

vim
:w !sudo tee % 
# 内容が出力される

それぞれ意味は
w: 保存
!: その後のコマンドを指示
sudo: 管理者権限で実行
tee: ファイルの出力と標準出力を同時に行うコマンド。sudoと組み合わせるとファイルの上書きが可能
%: 現在開いているファイルを指定

その後:q!で終了する。

vim
:q!

これで無事保存される。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む