タイトルが…長い…
概要
近頃CentOS6系でHTTPSな通信を行おうと思うと辛い(当社比)
HTTPSでリクエストした時にTLS1.2に対応していないクライアントをお断りしてくるページが増えているので、そういったところからデータを取ってこようとするとエラーになったりするわけでして。あと証明書エラーもめんどくさい。
こんな感じで詰まっている人たちは恐らくそれなりに居ると思っていて、 nss
を上げたり openssl
を上げたり試行錯誤して対応しているんじゃないかと想像。 yum
で epel
から取ってこようとしただけでエラーが出ることも有るっぽく地獄ですね。
Ansibleでもやっぱり詰まる。
get_url
なんかはリモート上のPythonで実行されているようで、PythonがTLS1.2をしゃべれないと死ぬ。証明書の問題も結局有る。CentOS6の標準なPythonは2.6なので辛い。
エラー例
例えば下記みたいなAnsibleを走らせようとしたら…
- name: Download NASM
get_url:
url: https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/nasm-2.13.03.tar.bz2
dest: ~/ffmpeg_sources
こんなエラーが出てしまうわけでして辛い。
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to validate the SSL certificate for www.nasm.us:443. Make sure your managed systems have a valid CA certificate installed. If the website serving the url uses SNI you need python >= 2.7.9 on your managed machine (the python executable used (/usr/bin/python2.6) is version: 2.6.6 (r266:84292, Jun 20 2019, 14:14:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)]) or you can install the `urllib3`, `pyOpenSSL`, `ndg-httpsclient`, and `pyasn1` python modules to perform SNI verification in python >= 2.6. You can use validate_certs=False if you do not need to confirm the servers identity but this is unsafe and not recommended. Paths checked for this platform: /etc/ssl/certs, /etc/pki/ca-trust/extracted/pem, /etc/pki/tls/certs, /usr/share/ca-certificates/cacert.org, /etc/ansible. The exception msg was: hostname 'www.nasm.us' doesn't match either of 'www.zytor.com', 'zytor.com'."}
ということで
そんなこんなでAnsibleで get_url
とかができなくて辛い思いをしたのでそれを解決した時のメモ。
戦略
yum
もPythonで動いているわけで、できれば標準でインストールされたPythonのバージョンは上げたくない。
ってことで以下みたいな方法で対応した。
- SCLでPython2.7をインストール
- 環境変数諸々を変更して以後のタスクを実行
リモート上で利用されているPythonを変更するには ansible_python_interpreter
変数を書き換えれば良いらしい。
--extra-vars
で ansbile-playbook
コマンドから直接設定するのでも良いし、inventoryで設定したりPlaybook内の set_fact
で設定しても良い。
ただ、これを設定するだけでは各種環境変数等々が不足して動かない可能性があることを気をつけたい。適宜 environment
で良い感じに環境変数を設定したほうが良さげ。
こんなAnsibleを書いた
例えば install.yml
の中身をPython2.7で実行したい場合…
- name: If CentOS 6
block:
- name: Install Python2.7
yum: name={{ item }}
with_items:
- centos-release-scl-rh
- python27
- set_fact:
custum_env:
PATH: "/opt/rh/python27/root/usr/bin:{{ ansible_env.PATH }}"
LD_LIBRARY_PATH: "/opt/rh/python27/root/usr/lib64"
MANPATH: "/opt/rh/python27/root/usr/share/man"
XDG_DATA_DIRS: "/opt/rh/python27/root/usr/share"
PKG_CONFIG_PATH: "/opt/rh/python27/root/usr/lib64/pkgconfig"
ansible_python_interpreter: "/opt/rh/python27/root/usr/bin/python"
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "6"
- name: Setup Tools Install
include: install.yml
environment: "{{ custum_env }}"
- set_fact:
ansible_python_interpreter: "python"
恐らく set_fact
で定義している LD_LIBRARY_PATH
とかは、真面目にやるなら固定値ではなく ansible_env.LD_LIBRARY_PATH
とかでデータを抜き出してこねくり回した方が良いとは思う。
めんどくさいからあんまりちゃんとやってないけど。
あと最後に ansible_python_interpreter: "python"
をやることでそれ以降の処理に影響が出ないようにしている(例えば yum
を叩く時はPythonは2.6に戻したほうが無難)
場合によっては witch
とかでいい感じに python
のパスを予め取得しておいたほうが良いのかもしれない。
ちなみにSSLなエラーという文脈でいうと、git
等のnss
を上げればいい感じに動きそうなやつはnss
を上げるだけで幸せになれそう。
総評
CentOS8が出た昨今、CentOS6とは早々におさらばしたほうが良い気がするし個人的にはUbuntuを使いたい(ぼそっ