カテゴリー別アーカイブ: Linux

LetsEncryptの証明書更新でError getting validation data

LetsEncryptの証明書更新でエラーが起きていたので対処。

certbot certonlyで証明書を更新する際に、以下のようなエラーが起きました。

Failed authorization procedure. sakaki333.com (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Error getting validation data

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: sakaki333.com
   Type:   connection
   Detail: Error getting validation data

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

エラーの内容は「サーバーには到達できたが、確認データの取得でエラーが起きました。DNSの設定とかIPアドレスが正しいかなどチェックしてください。」という感じでしょうか。

今まで普通に成功していたのでおかしいと思いDNSの設定やらルーターからの経路やらを確認しましたが、怪しい部分は発見できず。

結局何もわからず最後の手段と思い、ubuntuを更新してrebootしてみました。

# apt update
# apt upgrade
# reboot

再起動後にもう一度試すと、今度はなんと成功しました。

SSL関連のパッケージが更新された影響でしょうか。どちらにせよ、解決できてほっとしました。

それにしても、このエラー文で解決策がパッケージのアップデートとは、なかなか不親切ですね・・・

PQI Air Card向けにSSL付きcurlをコンパイル(まとめ)

以前からPQI Air Card向けにcurlをコンパイルしてきましたが、かなりハマったため記事が数回に分かれてまとまりがなくなっていました。

今までの記事

そこで、今度届くPQI Air Penの予習も兼ねてcurlのコンパイルをいまいちどまとめて見ようと思います。

今回作ったファイルは、こちらに置いておきます。

[http://wp.sakaki333.com/wp-content/uploads/2017/01/curl_pqi.tar.gz]

バイナリとライブラリをコピーするなりして使っていただけると幸いです。

環境

  • ubuntu 16.04 64bit(VM)
  • こちらの記事でsshやbusyboxなど導入済みのPQI Air Card

準備

まずはコンパイラを準備します。コンパイラは32bit向けのものを使うため、32ビットバイナリが動くようにしておきます。

$ sudo apt-get install lib32z1

作業ディレクトリを作っておきます。

$ mkdir -p ~/pqi/bin
$ mkdir ~/pqi/source
$ cd ~/pqi

コンパイラは、ここから取得します。

$ wget https://sourcery.mentor.com/public/gnu_toolchain/arm-none-linux-gnueabi/arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
$ tar xf arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
$ mv arm-2010q1 arm-dev
$ export PATH=$PATH:~/pqi/arm-dev/bin

arm-でタブを打って、補完が効くか確かめます。

$ arm-none-linux-gnueabi-[TAB]
arm-none-linux-gnueabi-addr2line  arm-none-linux-gnueabi-g++        arm-none-linux-gnueabi-gprof      arm-none-linux-gnueabi-readelf
arm-none-linux-gnueabi-ar         arm-none-linux-gnueabi-gcc        arm-none-linux-gnueabi-ld         arm-none-linux-gnueabi-size
arm-none-linux-gnueabi-as         arm-none-linux-gnueabi-gcc-4.4.1  arm-none-linux-gnueabi-nm         arm-none-linux-gnueabi-sprite
arm-none-linux-gnueabi-c++        arm-none-linux-gnueabi-gcov       arm-none-linux-gnueabi-objcopy    arm-none-linux-gnueabi-strings
arm-none-linux-gnueabi-c++filt    arm-none-linux-gnueabi-gdb        arm-none-linux-gnueabi-objdump    arm-none-linux-gnueabi-strip
arm-none-linux-gnueabi-cpp        arm-none-linux-gnueabi-gdbtui     arm-none-linux-gnueabi-ranlib

依存ライブラリをコンパイル

コンパイラができたので、まずはzlibをコンパイルします。

$ cd ~/pqi/source
$ git clone git://github.com/madler/zlib.git
$ cd zlib
$ git checkout -b work_1.2.8 v1.2.8
$ export CC=arm-none-linux-gnueabi-gcc
$ ./configure --prefix=$HOME/pqi/bin/zlib
$ make 
$ make install

次にopensslをコンパイルです。

$ cd ~/pqi/source
$ wget https://www.openssl.org/source/openssl-1.0.2j.tar.gz
$ tar xf openssl-1.0.2j.tar.gz
$ cd openssl-1.0.2j
$ ./Configure dist --prefix=$HOME/pqi/bin/openssl
$ make CC="arm-none-linux-gnueabi-gcc" AR="arm-none-linux-gnueabi-ar r" RANLIB="arm-none-linux-gnueabi-ranlib"
$ make install

curlをクロスコンパイル

$ cd ~/pqi/source
$ wget http://curl.haxx.se/download/curl-7.37.1.tar.gz
$ tar xf curl-7.37.1.tar.gz
$ export ROOTDIR="${PWD}"
$ cd curl-7.37.1/
$ export CROSS_COMPILE="arm-none-linux-gnueabi"
$ export CPPFLAGS="-I${HOME}/pqi/bin/openssl/include -I${HOME}/pqi/bin/zlib/include"
$ export LDFLAGS="-L${HOME}/pqi/bin/openssl/lib -L${HOME}/pqi/bin/zlib/lib"
$ export AR=${CROSS_COMPILE}-ar
$ export AS=${CROSS_COMPILE}-as
$ export LD=${CROSS_COMPILE}-ld
$ export RANLIB=${CROSS_COMPILE}-ranlib
$ export CC=${CROSS_COMPILE}-gcc
$ export NM=${CROSS_COMPILE}-nm
$ export LIBS="-lssl -lcrypto"
$ ./configure --prefix=${HOME}/pqi/bin/curl --target=${CROSS_COMPILE} --host=${CROSS_COMPILE} --build=x86_64-pc-linux-gnu --with-ssl --with-zlib
$ make
$ make install

前回はエラーが出たりもしましたが、今回はすんなりと通りました。

ちなみに生成されたディレクトリは以下のようになっていました。

├── bin
│   ├── curl
│   └── curl-config
├── include
│   └── curl
│       ├── curl.h
│       ├── curlbuild.h
│       ├── curlrules.h
│       ├── curlver.h
│       ├── easy.h
│       ├── mprintf.h
│       ├── multi.h
│       ├── stdcheaders.h
│       └── typecheck-gcc.h
├── lib
│   ├── libcurl.a
│   ├── libcurl.la
│   ├── libcurl.so -> libcurl.so.4.3.0
│   ├── libcurl.so.4 -> libcurl.so.4.3.0
│   ├── libcurl.so.4.3.0
│   └── pkgconfig
│       └── libcurl.pc
(略)

容量を減らすためにstripしておきます。

$ cd ~/pqi/bin/curl/lib
$ arm-none-linux-gnueabi-strip libcurl.so.4.3.0

これでもともと2.5MBだったライブラリが2.1MBくらいに減りました。

ファイルのコピー

さて、前回はman以外は全部コピーしていましたが、よく考えたら普通にヘッダーとか要りませんよね。

てことで、コピーするのはバイナリとライブラリだけにします。

さらに、前回はシンボリックリンクのライブラリをFAT32に置けるようにフルコピーしていましたが、今回は読み込んでくれそうな名前にリネームして1つだけ置くことにしました。

手元のLinuxのcurlがlibcurl.so.4を参照していたので、それに合わせてリネームします。

$ cp ~/pqi/bin/curl/bin/curl* /path/to/pqi/DCIM/122_TREK/usr/bin/
$ cp ~/pqi/bin/curl/lib/libcurl.so.4.3.0 /path/to/pqi/DCIM/122_TREK/usr/lib/libcurl.so.4
$ ls /path/to/pqi/DCIM/122_TREK/usr/bin
curl curl-config
$ ls /path/to/pqi/DCIM/122_TREK/usr/lib
libcurl.so.4

PQI Air Cardを再起動させた後にSSHして、curlを実行してみます。

$ ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 root@(PQI Air CardのIPアドレス)
# curl
curl: try 'curl --help' or 'curl --manual' for more information
# curl -k "https://raw.githubusercontent.com/github/gitignore/master/Java.gitignore"
*.class

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

無事にできているようですね!

前回の反省も含めて色々と改善してみましたが、設置するファイルも減って満足です。

まだまだ勉強不足かと思いますし、ご指摘あれば何なりと言ってください!

PQI Air Card用のcurlバイナリ

新しい記事を書きました

これまでいくつかの記事でPQI Air Card向けにCurlをクロスコンパイルする記事を書きましたが、いちおう作ったバイナリをアップロードしておきます。

https://drive.google.com/file/d/0B-3u42eq1U4WRkhFZlR3MlBSSEE/view?usp=sharing

なお、とりあえず動けばよかったのでstripやファイルの整頓などをちゃんと行っていません。

実機に入れ直して動くかなどもきちんと確認していないのでいろいろと申し訳ないのですが、とりあえずcurl関連で作ったファイルを入れておきました。autorun.shでリンクするなどして使っていただければと思います。

何か問題などありましたら、コメントなど残していただけるととても助かります。

【Windows】Bluetoothのリンクキーをスクリプトから取得

少し前にBluetoothキーボードをUbuntuとWindowsで共有する話を書きましたが、何度かペアリングしているうちに両方で登録する手順が面倒に感じてきました。

ペアリング作業だけならともかく、レジストリキーを取得するのは面倒すぎます。

そこで、取得作業をなるべく自動化するべくスクリプトを組むことにしました。

環境

  • Ubuntu 16.04 64bit
  • Windows 10 IP 64bit
  • Microsoft Wedge Mobile Keyboard

リンクキーの取り方

以前もお話ししましたが、Bluetoohで使うリンクキーはレジストリエディタから次のキーから取得できます。

(Pythonで組んだのでバックスラッシュが2つになっています・・・)

HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\services\\BTHPORT\\Parameters\\Keys

また、リンクキーを表示する場合は権限の問題でPSExecというツールからコマンドを発行する必要があります。

そこで、PSExecからregeditをCLIモードで呼び出すべく、次のコマンドを発行しました。

管理者権限でPowerShellを起動して、PSExecがあるディレクトリに移動します。

PS ~\PSTools> .\PsExec.exe -s -i REGEDIT /E D:\temp\test.REG "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\BTHPORT\Parameters\Keys
PS ~\PSTools> cat D:\temp\test.REG
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\BTHPORT\Parameters\Keys]

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\BTHPORT\Parameters\Keys\(BTアダプタのアドレス)]
"(デバイスのMACアドレス)"=hex:(リンクキー)
"(デバイスのMACアドレス)"=hex:(リンクキー)
(略)

のような出力が得られるはずです。

ただ、これだとどのアドレスがどのデバイスに紐づいているかが分からないので、https://macvendors.com/api を使わせてもらってベンダー情報を取得します。

このAPIは、MACアドレスの上位6桁を送信するとベンダーを返してくれるものです。

PS \PSTools> curl "http://api.macvendors.com/7c1e52"


StatusCode        : 200
StatusDescription : OK
Content           : Microsoft
RawContent        : HTTP/1.1 200 OK
                    Access-Control-Allow-Origin: *
                    Content-Length: 9
                    Content-Type: text/plain
                    Date: Tue, 29 Nov 2016 05:41:26 GMT

                    Microsoft
Forms             : {}
Headers           : {[Access-Control-Allow-Origin, *], [Content-Length, 9], [Content-Type, text/plain], [Date, Tue, 29 Nov 2016 05:
                    41:26 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : System.__ComObject
RawContentLength  : 9

製品情報までは取れませんが、今回はMicrosoftが作っているデバイスが分かればいいので良しとします。

これらを組み合わせてスクリプトを書きます。

スクリプト

PSToolsのディレクトリがスクリプトと同じディレクトリにある状態で実行できます。

#!/usr/bin/env python3.5
# -*- coding:utf-8 -*-

import os
import json
import time
import requests
from subprocess import call

current_dir = os.path.dirname(os.path.abspath(__file__)).replace("/", os.path.sep)


def get_keys():
    cmdfmt = current_dir + '\\PSTools\\PsExec.exe -s -i REGEDIT /E {path} ' \
             '"HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\services\\BTHPORT\\Parameters\\Keys"'
    filename = current_dir + "\\temp.REG"
    cmd = cmdfmt.format(path=filename)
    try:
        call(cmd, shell=True)
        with open(filename, "r") as f:
            reginfo_raw = f.read().replace("\x00", "")
    except Exception as e:
        print(e)
        reginfo_raw = ""
    finally:
        if os.path.exists(filename):
            os.remove(filename)
    reginfo = reginfo_raw.split('"')[1:]
    return [{"macaddr": reginfo[i], "key": reginfo[i+1][5:-2]} for i in range(0, len(reginfo), 2)]


def recv_vendor(macaddr):
    time.sleep(0.5)
    return requests.get("http://api.macvendors.com/" + macaddr[:6]).text

if __name__ == "__main__":
    keys = get_keys()
    for key in keys:
        key.update({"vendor": recv_vendor(key["macaddr"])})
    print(json.dumps(keys, indent=4, separators=(',', ': ')))

ポイントはPsExecの出力ファイルがUnicode形式だったので、f.read()する時にreplace(“\x00”, “”)しているあたりですかね。。

もっと行儀のよい方法があったら教えていただけるとありがたいです。

これを実行すると、

PS \regshow> python .\regedit.py

PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com


REGEDIT exited on SAKAKI-MOBILE with error code 0.
[
(略)
    {
        "macaddr": "(デバイスのMACアドレス)",
        "key": "(リンクキー)",
        "vendor": "Microsoft"
    }
]

いい感じに自動化できました。

これからはじゃんじゃんOS間でペアリングしていきますよ!

Windows10とUbuntu16.04でBluetoothデバイスを共有

タブレットでUbuntuとWindowsをデュアルブートして使っているのですが、Bluetoothキーボードをデュアルブートで使っていると取り回しがとても悪いですよね。

共有できる方法を調べて、少し工夫するとうまくいったのでメモを残します。

こちらの記事を参考にさせていただきました。

環境

  • Ubuntu 16.04 64bit
  • Windows 10 Insider Preview Build 14931
  • Microsoft Wedge Mobile Keyboard

手順

※ Markdownのコードブロックがうまく動かなかったので、変な書き方になってしまいました。すみません・・・

  1. まず、普通にUbuntuでペアリングした後に普通にWindowsでもペアリングします。
  2. その後、ここからPsToolsをダウンロードします。
  3. 展開したら管理者権限でコマンドプロンプトを開き、展開したディレクトリに移動します。
  4. 次のコマンドを実行します
    PsExec.exe -s -i regedit.exe
  5. レジストリエディタが起動するので、次の場所を探してください。(元記事だとControlSet002でしたが、私の環境だとControlSet001にありました)
    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\B THPORT\Parameters\Keys\xxxxxxxxxxxx(BluetoothアダプタのMACアドレス?)
  6. ペアリングしたデバイスのMACアドレスが名前となったレジストリキーの値をメモします。
  7. Ubuntu側で以下のファイルを管理者権限で開きます。
    /var/lib/bluetooth/XX:XX:XX:XX:XX:XX/YY:YY:YY:YY:YY:YY(ペアリングしたいデバイスのMACアドレス)/info
  8. LinkKey項目内のKeyをメモしたものに編集します(大文字&スペース無し)
    [LinkKey]
    Key=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ(メモしたリンクキー)
  9. 再起動します

これで、Bluetoothデバイスが複数OSで使えるようになっているはずです。

リンクキーを共有できれば、Bluetoothデバイスを複数環境下で使えるんですね。

PQI Air Cardのowncloud同期スクリプト書いてみた

何度目になるかわかりませんが、PQI Air Cardネタです。

以前からPQI Air Cardで自動同期する方法を模索しており、前回まででPythonとcURLをクロスコンパイルして導入しました。

なお、用途としてはデジカメの撮影画像やPS4のスクリーンショットなどを自動的にowncloudに同期したい、という感じです。

せっかくPythonとCurlを導入したので、今回は自動同期のスクリプトをPythonで書いてみることにしました。

流れ

  1. ネットワークに接続されるまで待機
  2. curlでowncloud側のファイル一覧を取得
  3. 対象のファイルがowncloudに存在しなければ送信

2と3はcurlコマンドで実現可能ですので、subprocessからcurlを呼ぶことで全て任せました。

send_picture.py

#!/usr/bin/env python2.7
# -*- coding:utf-8 -*-

import os, subprocess, json, time, urllib

path = os.path.abspath(os.path.dirname(__file__))

if subprocess.check_output("ps").count("python") > 1:
print "Another sync process is running."
exit(0)

while "192.168" not in subprocess.check_output("ifconfig"):
time.sleep(3)

with open(path + "/config.json", "r") as f:
configs = json.loads(f.read())
for index, config in enumerate(configs):
for key, value in config.items():
configs[index][key] = value.encode("utf-8")

with open(path + "/suffixes.json", "r") as f:
suffixes = json.loads(f.read())

def list_owncloud_pics(config):
precmd = "curl -k -X PROPFIND -u {username}:{password} \"{url}\""
cmd = precmd.format(**config)
print cmd
raw = subprocess.check_output(cmd, shell=True)

def is_file_name(elem):
for suffix in suffixes:
if elem.endswith(suffix):
return True
files = list(filter(is_file_name, raw.replace("<", "/").split("/")))
return list(map(lambda f: urllib.unquote(f), files))

def push_file(config, picture):
precmd = "curl -k -X PUT -u {username}:{password} \"{url}/{picture}\" --data-binary @\"{destination}/{picture}\""
cmd = precmd.format(picture=picture, **config)
print cmd
subprocess.call(cmd, shell=True)

def backup(config):
uploaded = list_owncloud_pics(config)
dirpath = config["destination"]
files = os.listdir(dirpath)
for picture in files:
if True not in map(lambda suffix: picture.endswith(suffix.encode("utf-8")), suffixes):
continue
if picture in uploaded:
continue
push_file(config, picture)

while True:
for config in configs:
backup(config)
print "sleeping..."
time.sleep(10)

config.json

[{
"url": "https://yourowncloud.com",
"username": "username",
"password": "password",
"destination": "/path/to/your/picture_dir"
}]

suffixes.json

[".JPG", ".jpg", ".PNG", ".png", ".jpeg"]

なぐり書きしたプログラムなので非常にお粗末で申し訳ないですが、一応私の環境では動作しているのでお許しください。。

注意点として、まずPQI Air Cardではこれを走らせる事しか考えていないので、複数起動防止としてpsでPythonプロセスが走っているかチェックを行っています。

また、ifconfigで192.168..の文字列が出力されるかでネットワーク疎通のチェックを行っているので、環境によっては普通に動きません・・・

エラー処理も全く書いていないので、失敗するとプログラムが止まります。

当方ではautorun.shとcronで毎分起動することでなんとか運用していますが、暇があればもう少し改良したいですねぇ〜

試してみた

Linuxのowncloudをインストールした環境で、自動同期を試してみました。

PS4のスクリーンショットのディレクトリをconfig.jsonに登録してしばらく待ってみると、ちゃんとPQI Air Card内の画像が手元のPCにダウンロードされているのが確認できました。

screenshot-from-2016-10-17-18-42-26

これで、ようやく家でも出先でも快適なSDカードライフが送れそうです…

【Ubuntu】Alt+クリックでウィンドウ移動のホットキーを変更

発端

PyCharmのマルチカーソル機能を使いたかったのですが、Ubuntuの機能であるウィンドウ移動とホットキー(Alt+クリック)が被っていたので変更しました。

手順が意外と面倒だったので書いておきます。

手順

このサイトを参考にしました。

まず、ウィンドウマネージャの装飾機能の管理ツールをインストールします。

sudo apt-get install compizconfig-settings-manager

これでCompizConfig Setting Managerというアプリケーションが入ったので、起動します。

検索窓からMoveと入れると、「ウィンドウの移動」が出ると思います。

screenshot-from-2016-10-14-15-49-42

これをクリックして詳細を開くと、「ウィンドウの移動開始」という項目があります。

ここを無効化するのではなく、別のキーを割り当てる事がポイントです。

ウィンドウの移動はUbuntuのウィンドウマネージャの動作に必須なので、無効化しても強制的に有効化されます。

プラグイン自体を無効化するとウィンドウマネージャが終了して面倒なことになるので注意が必要です。

screenshot-from-2016-10-14-15-49-56

別のキーを割り当てたら、作業終了です。

今度からカッコいい複数ライン選択をバリバリ使ってくぞ!!

PQI Air CardにSSHする

これまで何回かPQI Air Cardに関する記事を書いてきましたが、SSHにもちょっとした工夫が必要なので書いておきます。

普通にSSHしようとすると、

$ ssh user@ip
Unable to negotiate with ip port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1

となり拒否されてしまいます。

これはPQI Air CardのSSHが使っている暗号化の方式が古いことで起きるエラーなので、ローカルから接続する場合は許容するようにしてしまいましょう。

$ ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 user@ip

【完結】PQI Air CardでSSL付きのcurlを動かす


追記 2017/01/19

さらに新しい記事を書きました

http://wp.sakaki333.com/2017/01/19/post-870/ にバイナリ置いておきました。

粗末なものですが、よかったら使ってくださいね〜


前回の記事でPQI Air Card向けにcurlをクロスコンパイルしました。

あとは実機で動作確認だけだと意気込みましたが、実際のところ昨日までaptでぬるま湯に浸かっていた素人がクロスコンパイルしたバイナリが動くわけ無いですよね・・・

今回は、なんとか動作するまでこぎつけましたので、その記録を書いていきます。

バイナリをコピー

PQI Air Cardのカスタマイズはおおよそこの記事がベースになっていまして、この方がPQI Air CardのCPUで動く様々なバイナリを作ってくださっています。

今回の記事もこれらのバイナリを導入済みで書いているので、インストールはこの記事の方針に合わせます。

まず、コンパイルされたcurlバイナリをPQI Air Cardの DCIM/122_TREK/usr 以下にコピーします。

$ cd /path/to/PQI_Air_Card/DCIM/122_TREK/usr
$ cp -r ~/curlArm/bin ./bin
$ cp -r ~/curlArm/include ./include
$ cp -r ~/curlArm/lib ./lib

私はファイルマネージャから行ったので出力は違うかもしれませんが、シンボリックリンクがサポートされていませんとエラーが出ました。

この環境でPQI Air Card上でバイナリを実行するとセグフォが出ます。

# curl
Segmentation Fault

悲しいことにこれの原因がライブラリ不足だと気付くのにしばらくかかってしまいました。

FATはシンボリックリンクをサポートしていないので、ライブラリが参照できなかったのですね。

ライブラリをコピーして、必要なファイルを作成しました。

$ cd lib
$ cp libcurl.so.4.3.0 libcurl.so.4
$ cp libcurl.so.4.3.0 libcurl.so

これで実行すると、お次はこんなエラーが。。

# curl
curl: /lib/libc.so.6: version `GLIBC_2.17' not found (required by curl)
curl: /lib/libc.so.6: version `GLIBC_2.17' not found (required by libcurl.so.4)

調べてみると、これはlibcのバージョンが低いために起きるエラーらしいです。

早速PQI Air Cardのバージョンを確認してみると、

# /lib/libc.so.6
GNU C Library (Sourcery CodeBench Lite 2011.09-70) stable release version 2.13, by Roland McGrath et al.
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.6.1.
Compiled on a Linux 3.0.1 system on 2011-12-07.
Available extensions:
    crypt add-on version 2.1 by Michael Glad and others
    GNU Libidn by Simon Josefsson
    Native POSIX Threads Library by Ulrich Drepper et al
    Support for some architectures added on, not maintained in glibc core.
    BIND-8.2.3-T5B
libc ABIs: UNIQUE
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>

なるほど、libcのバージョンは2.13なので、要求されている2.17には届いていないですね。

しばらく調べましたが、このサイトによると、必要なlibcのバージョンはコンパイラによって決定されるそうです。

つまり、今使っているコンパイラが必要としているlibcのバージョンが高すぎる事が原因らしいのですが、だったら何故Pythonはコンパイルできたのだろうか・・・

考えていても仕方がないので、新しい(というか実際は”もっと古い”ですが笑)コンパイラを探しに行きます。

なお、libcはC言語のバイナリの基本的な命令を実行するために必要な最重要ライブラリで、システムにある他のライブラリとも密に連携しています。

libcのアップデートはかなり危険っぽいので、やめておいたほうが良いと思います。

コンパイラを入手

今回はいくつか試しましたが、正常に動いたものはここからダウンロードできます。

入っているコンパイラの実行ファイルのファイル構成はほぼ一緒ですので、コンパイラは置き換えてください。

zlibとopensslを再度ビルド

前回の記事と同じようにコンパイルし直します。

ただ、opensslのmake中に何故かコンパイラのパスが変に設定されていたので、シンボリックリンクを貼って一時しのぎをしました。

/bin/sh: 6: arm-none-linux-gnueabiranlib: not found
Makefile:540: ターゲット 'install_sw' のレシピで失敗しました
make: *** [install_sw] エラー 127
$ cd /path/to/arm_compiler
$ ln -s arm-none-linux-gnueabi-ranlib arm-none-linux-gnueabiranlib

何か環境変数がおかしな設定になっていたのでしょうか。

変な対応方法になってしまいましたが、これでうまくいったので良しとします。。

curlを再ビルド

では、いよいよ再度curlをビルドします。

方法は前回と同じです。

ただし、./configureの出力に違いが現れました。

  curl version:     7.37.1
  Host setup:       arm-none-linux-gnueabi
  Install prefix:   /home/sakaki/curlArm
  Compiler:         arm-none-linux-gnueabi-gcc
  SSL support:      enabled (OpenSSL)
  SSH support:      no      (--with-libssh2)
  zlib support:     enabled
  GSS-API support:  no      (--with-gssapi)
  SPNEGO support:   no      (--with-spnego)
  TLS-SRP support:  enabled
  resolver:         default (--enable-ares / --enable-threaded-resolver)
  ipv6 support:     no      (--enable-ipv6)
  IDN support:      no      (--with-{libidn,winidn})
  Build libcurl:    Shared=yes, Static=yes
  Built-in manual:  enabled
  --libcurl option: enabled (--disable-libcurl-option)
  Verbose errors:   enabled (--disable-verbose)
  SSPI support:     no      (--enable-sspi)
  ca cert bundle:   no
  ca cert path:     no
  LDAP support:     no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
  LDAPS support:    no      (--enable-ldaps)
  RTSP support:     enabled
  RTMP support:     no      (--with-librtmp)
  metalink support: no      (--with-libmetalink)
  HTTP2 support:    disabled (--with-nghttp2)
  Protocols:        DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMTP SMTPS TELNET TFTP

前回無効になっていたzlibが有効になっています。なんか知らんけどやったね!

ビルドが完了したら、再びシンボリックリンクを手動コピーしてSDカードへコピーします。

いよいよ実行へ

ここまで長い時間がかかりましたが、やっと実行できるバイナリができました。

実行時にSSL証明書のエラーが出ましたが、今回は証明書チェックは行わないので-kオプションで無視するようにします。

$ touch "abc" > /root/test.txt
$ curl -k -X PUT -u username:password "https://yourowncloud.com/remote.php/webdav/Photo/test.txt" --data-binary @"/root/test.txt"

これでowncloudにtest.txtがアップロードされていれば、作業は完了です。

クロスコンパイルは環境依存な部分が多くて大変なのは知っていましたが、やっぱりよくわからない部分が多くて大変でした。

今回なんとかcurlのビルドに成功したので、他にほしいバイナリがあったら再びビルドに挑戦してみようと思います。

PQI Air Card向けにcURLをクロスコンパイル

新しい記事を書きました

前回の続きです。

また、実際に成功した記事は次回になります

目的

PQI Air Cardで動くSSL enabledなcurlを手に入れたい。

前回の記事で環境構築→Pythonをビルドできたので、今回はいよいよ本命のcurlをビルドします。

SSL無しで

まずは普通にconfigureしてみました。

エラーは出ませんでしたが、SSLのサポートが無いのがわかります。

  curl version:     7.37.1
  Host setup:       arm-none-linux-gnueabi
  Install prefix:   /usr
  Compiler:         arm-none-linux-gnueabi-gcc
  SSL support:      no      (--with-{ssl,gnutls,nss,polarssl,cyassl,axtls,winssl,darwinssl} )
  SSH support:      no      (--with-libssh2)
  zlib support:     no      (--with-zlib)
  GSS-API support:  no      (--with-gssapi)
  SPNEGO support:   no      (--with-spnego)
  TLS-SRP support:  no      (--enable-tls-srp)
  resolver:         default (--enable-ares / --enable-threaded-resolver)
  ipv6 support:     no      (--enable-ipv6)
  IDN support:      no      (--with-{libidn,winidn})
  Build libcurl:    Shared=yes, Static=no
  Built-in manual:  enabled
  --libcurl option: enabled (--disable-libcurl-option)
  Verbose errors:   enabled (--disable-verbose)
  SSPI support:     no      (--enable-sspi)
  ca cert bundle:   no
  ca cert path:     no
  LDAP support:     no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
  LDAPS support:    no      (--enable-ldaps)
  RTSP support:     enabled
  RTMP support:     no      (--with-librtmp)
  metalink support: no      (--with-libmetalink)
  HTTP2 support:    disabled (--with-nghttp2)
  Protocols:        DICT FILE FTP GOPHER HTTP IMAP POP3 RTSP SMTP TELNET TFTP

zlibをビルド

紆余曲折しましたが、このページを参考にしました。

後のopensslのビルドもこれを参考にしています。

$ git clone git://github.com/madler/zlib.git
$ cd zlib
$ git checkout -b work_1.2.8 v1.2.8
$ CC=arm-none-linux-gnueabi-gcc
$ ./configure --prefix=$HOME/zlibArm
$ make 
$ make install

opensslをビルド

$ wget https://www.openssl.org/source/openssl-1.0.2j.tar.gz
$ tar zxf openssl-1.0.2j.tar.gz
$ export cross=arm-none-linux-gnueabi-
$ cd openssl-1.0.2j
$ ./Configure dist --prefix=$HOME/opensslArm
$ make CC="${cross}gcc" AR="${cross}ar r" RANLIB="${cross}ranlib"
$ make install

cURLをビルド

いよいよcURLをビルドします。

ビルドにあたり、このページを参考にしました。

$ wget http://curl.haxx.se/download/curl-7.37.1.tar.gz
$ tar xzf curl-7.37.1.tar.gz
$ export ROOTDIR="${PWD}"
$ cd curl-7.37.1/
$ export CROSS_COMPILE="arm-none-linux-gnueabi"
$ export CPPFLAGS="-I${HOME}/opensslArm/include -I${HOME}/zlibArm/include"
$ export LDFLAGS="-L${HOME}/opensslArm/lib -L${HOME}/zlibArm/lib"
$ export AR=${CROSS_COMPILE}-ar
$ export AS=${CROSS_COMPILE}-as
$ export LD=${CROSS_COMPILE}-ld
$ export RANLIB=${CROSS_COMPILE}-ranlib
$ export CC=${CROSS_COMPILE}-gcc
$ export NM=${CROSS_COMPILE}-nm
$ export LIBS="-lssl -lcrypto"
$ ./configure --prefix=${HOME}/curlArm --target=${CROSS_COMPILE} --host=${CROSS_COMPILE} --build=x86_64-pc-linux-gnu --with-ssl --with-zlib

ちなみにcurl-7.50.3でビルドを試みましたが、謎のエラーで3回ほどつまづき、ビルドすることができませんでした。。

$ ./configure ~~~
(略)
configure: error: in `/home/sakaki/temp/curl-7.50.3':
$ vim configure
(4300行目あたりの-V -vquestionオプションを削除)
$ ./configure ~~~
(略)
configure: error: Unable to link function recv

curl-7.37.1だと素直にconfigureできました。

時間があったら他のバージョンも試してみようと思います。

で、configureの結果ですが、

  curl version:     7.37.1
  Host setup:       arm-none-linux-gnueabi
  Install prefix:   /home/sakaki/curlArm
  Compiler:         arm-none-linux-gnueabi-gcc
  SSL support:      enabled (OpenSSL)
  SSH support:      no      (--with-libssh2)
  zlib support:     no      (--with-zlib)
  GSS-API support:  no      (--with-gssapi)
  SPNEGO support:   no      (--with-spnego)
  TLS-SRP support:  enabled
  resolver:         default (--enable-ares / --enable-threaded-resolver)
  ipv6 support:     no      (--enable-ipv6)
  IDN support:      no      (--with-{libidn,winidn})
  Build libcurl:    Shared=yes, Static=yes
  Built-in manual:  enabled
  --libcurl option: enabled (--disable-libcurl-option)
  Verbose errors:   enabled (--disable-verbose)
  SSPI support:     no      (--enable-sspi)
  ca cert bundle:   no
  ca cert path:     no
  LDAP support:     no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
  LDAPS support:    no      (--enable-ldaps)
  RTSP support:     enabled
  RTMP support:     no      (--with-librtmp)
  metalink support: no      (--with-libmetalink)
  HTTP2 support:    disabled (--with-nghttp2)
  Protocols:        DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMTP SMTPS TELNET TFTP

これでSSLが有効になりました。

あれ、でもzlibが有効になっていませんね。どうしてでしょう。。

問題無さそうなので、そのまま進めます。

いよいよビルドです。

$ make
$ make install

ビルドの結果は問題無さそうです。

あとはこれを実機で試してみるのみとなりました。

ダメだったらどうしようかな(白目)


※追記(2016/10/10)※

やっぱりダメでした・・・でも最後は動いたよ→記事

参考

  • http://memo.saitodev.com/home/arm/arm_cross_compile/#openssl
  • http://www.matteomattei.com/how-to-cross-compile-curl-library-with-ssl-and-zlib-support/
  • http://yasuhide.blog.jp/archives/43019157.html
  • http://stackoverflow.com/questions/11841919/cross-compile-openssh-for-arm
  • http://stackoverflow.com/questions/7561509/how-to-add-include-and-lib-paths-to-configure-make-cycle
  • http://qiita.com/ksugawara61/items/2dc6abd50077fd4b0c87
  • http://stackoverflow.com/questions/25979525/cannot-find-lssl-cannot-find-lcrypto-when-installing-mysql-python-using-mar

所感

私はソースからのコンパイルは数回しか経験が無く、クロスコンパイルに至っては今回が初めての経験です。

この記事にはほとんど書きませんでしたが、成功するまでにかなりの紆余曲折があり、curlをビルドするだけなのにとても疲れました。

また、普段はaptなどのパッケージ管理ツールに慣れてしまいコンパイル力が欠けていましたので、今回はそれを痛感する形となってしまいました。。

それにしても、クロスコンパイルしてみて改めてビルド周りのツール群の強力さがわかった気がします。

無数にあるCPUで正常に動くバイナリをちゃんと作成できるって、すごい事だと思います(超小並

今回は良い経験をさせていただきました。

それでは!