- 投稿日:2020-04-03T18:53:29+09:00
さすがに無いと思うが、古い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.solibssl.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.confListen 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
- 投稿日:2020-04-03T18:53:29+09:00
さすがに無いと思うが、古い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.solibssl.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.confListen 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
- 投稿日:2020-04-03T17:55:52+09:00
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)
やりたいこと : 踏み台の向こうにある置き場ホストに一発でファイルを転送したい
ファイルを接続元から踏み台において、踏み台から置き場において・・・というのが面倒くさい。
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
- 投稿日:2020-04-03T17:27:21+09:00
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="世… …中略… …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がおすすめです!
こちらは、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を使用します。
まずは-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億杯食べてきますね〜
当記事は下記記事の続きですが、「Linuxとかシェルって何?」を知っていればこの記事からでも読めます!【黒い画面恐怖症向け】Linuxとかシェルとかざっくり知りたいのでゆるく図解した ↩
GETとPOSTの違いはこちらのQiita記事が分かりやすいです! ↩
httpbinでは、デバッグ等に便利なようレスポンスにorigin等出してくれちゃうのですが、個人情報もあるため記事では伏せています! ↩
- 投稿日:2020-04-03T07:30:02+09:00
vimで読み取り専用ファイルを編集、保存する
EC2上でreadonlyファイルを編集しようとした時に一瞬詰まったので備忘録を。
やり方は2通りある。方法1:ファイルを開く段階でsudoコマンドを付ける
一番シンプルで一番簡単な方法。
ターミナル$ sudo vim 編集したいファイルを選択これならvimで編集後、普段通り:wqで保存が可能。
方法2:readonlyのまま編集したファイルを強制保存
これが一番よくあるパターンだと思う。てか私がなったからこれを書いているわけだが。
編集した後にそういやsudoで実行してない!となっても焦らず下記コマンドを叩けば良い。vim:w !sudo tee % # 内容が出力されるそれぞれ意味は
w: 保存
!: その後のコマンドを指示
sudo: 管理者権限で実行
tee: ファイルの出力と標準出力を同時に行うコマンド。sudoと組み合わせるとファイルの上書きが可能
%: 現在開いているファイルを指定その後:q!で終了する。
vim:q!これで無事保存される。