LoginSignup
1
0

More than 3 years have passed since last update.

CentOS6へAnsibleを流そうとした時にPython2.6起因なHTTPS関連のエラーが出ちゃうのをSCLを上手く使って何とかする

Last updated at Posted at 2019-10-16

タイトルが…長い…

概要

近頃CentOS6系でHTTPSな通信を行おうと思うと辛い(当社比)

HTTPSでリクエストした時にTLS1.2に対応していないクライアントをお断りしてくるページが増えているので、そういったところからデータを取ってこようとするとエラーになったりするわけでして。あと証明書エラーもめんどくさい。
こんな感じで詰まっている人たちは恐らくそれなりに居ると思っていて、 nss を上げたり openssl を上げたり試行錯誤して対応しているんじゃないかと想像。 yumepel から取ってこようとしただけでエラーが出ることも有るっぽく地獄ですね。

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のバージョンは上げたくない。
ってことで以下みたいな方法で対応した。

  1. SCLでPython2.7をインストール
  2. 環境変数諸々を変更して以後のタスクを実行

リモート上で利用されているPythonを変更するには ansible_python_interpreter 変数を書き換えれば良いらしい。
--extra-varsansbile-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を使いたい(ぼそっ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0