覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Windows - curlコマンド

Windows 10 は、標準でcurlコマンドが使えるようになってたんですね。(知らなかったです)

Windows標準のcurlについて、少しだけ確認してみました。


Wndows PowerShell 5.1

デフォルトでインストールされている Wndows PowerShell 5.1 環境で curl と実行してみたら以下のようになりました

PS C:\Users> curl

コマンド パイプライン位置 1 のコマンドレット Invoke-WebRequest
次のパラメーターに値を指定してください:
Uri:

何か思ってたのと違うので、よくよく確認してみたら
curl というコマンドは Invoke-WebRequest の Alias になってました。(以下の通り)

PS C:\Users> Get-Command curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           curl -> Invoke-WebRequest


PS C:\Users> Get-Command Invoke-WebRequest

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Invoke-WebRequest                                  3.1.0.0    Microsoft.PowerShell.Utility


ただし、実際には上記の curl とは関係なく、 curl.exe というものが標準でインストールされています。
curl.exe とやれば実行できます。(こっちのほうが想定してた curlコマンドに近いと思われます)

PS C:\Users> curl.exe
curl: try 'curl --help' for more information
PS C:\Users> Get-Command curl.exe

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     curl.exe                                           7.55.1.0   C:\WINDOWS\system32\curl.exe


PowerShell 7.1

標準の Windows PowerShell とは別で PowerShell 7.1 もインストールしているので、
そちらでも curlコマンドを確認してみました。今回確認した環境の情報(バージョン等)は以下の通りです。

PS C:\Users> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.3
PSEdition                      Core
GitCommitId                    7.1.3
OS                             Microsoft Windows 10.0.19042
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0


curlについて確認した結果は以下の通りです。

PS C:\Users> curl
curl: try 'curl --help' for more information
PS C:\Users> Get-Command curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     curl.exe                                           7.55.1.0   C:\WINDOWS\system32\curl.exe

こっちは最初から curlcurl.exe を指してます。(もしかしたら環境にもよるかもしれませんが)


ついでに curl --version も実行してみました。

PS C:\Users> curl --version
curl 7.55.1 (Windows) libcurl/7.55.1 WinSSL
Release-Date: 2017-11-14, security patched: 2019-11-05
Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL


話は、それますが DOSプロンプトでも curlcurl.exeC:\WINDOWS\system32\curl.exe) を指しています。


WSL

WSL (Ubuntu 20.04.2 LTS) での curl もついでに確認。

user01@PC-001:/mnt/c/Users$ curl
curl: try 'curl --help' or 'curl --manual' for more information
user01@PC-001:/mnt/c/Users$ which curl
/usr/bin/curl
user01@PC-001:/mnt/c/Users$ curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

Windows版標準のcurl.exeとは バージョン、扱えるプロトコル、機能 に差異があるようです。


まとめ・補足

  • curl と安易に実行しても、実行環境によって curl.exeだったり、そうでなかったりしています。
  • curl.exe は Windows用にビルドされた curl のためか、Linux上のcurlとは扱えるプロトコルやパラメータに差異があります。
  • (実行例が無いので分かりにくいですが) curl.exeでも、Linux用にビルドされているcurlとほぼ同じ操作ができます。


HTTPステータスコードだけ取得

以前書いたこのエントリをWindows標準のcurl.exeで実現する場合は以下のようになります。

curl -s {リクエスト先のURL} -o nul -w '%{http_code}\n'

上記は PowerShell 7.1 で実行する想定です。

Chrome - 開いていたタブを全部復元させたい

Webブラウザとして Google Chrome を使っていると、どんどんタブを開いてしまっていることは良くあると思います。

作業している間は別に問題ないんですが、

何らかの理由、例えば OS再起動をしなければならない, Chromeがメモリを食いすぎているので落としたい etc で、
Chrome自体を一旦終了させる必要がでてきた状況になった場合に、
今開いてる多数のタブを、次回 Chrome を起動した時にどうするんだ?ゼロから全部開きなおすのは辛い。

というのは意外にあるシチュエーションだと思います。

こういう状況だと再度Chromeを立ち上げ直した時には、もともと開いていた複数のタブをそのまま復元してほしい。
と思うことがあります。
この要望を達成するための設定や操作について以下に記載しています。

基本的に、Windows 版の バージョン: 90.0.X の Chrome をベースにして内容を書いてます。


起動時に前回開いていたタブを開くように設定する

Chrome 右上の (Chrome メニュー, Google Chrome の 設定)をクリックして開き、設定 をクリックします

f:id:nini_y:20210417153503p:plain

(ちなみに、Chromeメニューは Alt + F のショートカットで開けます)


設定項目の 「起動時」で、前回開いていたページを開く のラジオボタンを選択します。

f:id:nini_y:20210417153913p:plain


これで設定は完了です。


Chromeを終了させる

複数のタブが開いているような状況で、Chromeを終了させます。

ただし、このChromeの終了操作方法には注意が必要で、以下の操作で行います。


Chrome 右上の (Chrome メニュー)をクリックして開き、終了 をクリックします。

f:id:nini_y:20210417160824p:plain

上記操作は、 Alt + FX のキーボードショートカット でも実行できます。

これでChromeが終了し、開いていたタブの情報などが保存されます。


注意

例えば、Chrome を閉じるには ウインドウ右上の × クリック や Alt + F4 ショートカット でもできます。

これは1つのウィンドウでのみ Chrome を開いている場合には特に問題ありません。
この操作後に再度Chrome を起動する と開いていたタブが復元されます。

ただし、複数ウィンドウに分けてChromeを開いていた場合、× をクリックする操作では、最後に閉じたウィンドウ内のタブだけが保存されて、次回のChrome起動時にその最後に閉じたウィンドウのタブだけが復元されることになってしまいます。

マルチモニター環境などでは、複数のウィンドウにChromeをそれぞれ開いている という状況も十分にあると思います。
ですので、Chromeの終了操作(Alt + FX のキーボードショートカット )を行ってください

macOSの場合

macOS ではアプリ終了のショートカットが統一されていて、Chrome も Command + Q (警告出す場合は2回実行)で 終了できます。
その後、再度Chromeを起動すると、すべてのウィンドウとタブが復元されます。


起動時にタブを復元

設定 および Chromeの終了操作 を行っていれば、タブの復元は特に意識せずにChromeを起動した際に勝手に行われます。
正確にはタブだけではなく、各ウィンドウの表示サイズや位置も復元されます。

(OS再起動後でも復元されます)

というわけで、これでめでたくChromeにおけるタブの復元ができることが分かりました。


他のやり方とか

基本的に、上に書いた設定と操作でやりたいことは実現できます。

が、一応他にも見かけるやり方として、
Ctrl + Shit + D の操作で、現在開いているタブをすべてまとめてブックマークするという手法もあります。

ブックマークした後、xをクリックしてChromeを閉じて、

Chromeを次回起動した後に、保存したフォルダを右クリックして、”すべて(X個)を開く” クリックで復元できます。

f:id:nini_y:20210417160928p:plain


ただ、このやり方だと以下の操作が必要になります。

  • 各ウィンドウごとに、タブをブックマークする操作が必要になる。
  • Chrome起動後に、ウィンドウ単位でタブを開く操作が必要になる。
  • タブをブックマークしてしまうので、必要ないのであればブックマークを削除する必要がある

また、自分でそれぞれ復元させる操作を行っているので、ウィンドウ位置などの復元などは基本的に行われません。


まとめ

設定で、起動時の動作を "前回開いていたページを開く" にしておいて、Chromeの終了操作を行うのが
前回開いていたタブを復元する手段として一番簡単だと思います。

Windows - IPv6 より IPv4 を優先させたい

現在 Windows 10 を利用してる状況にあります。

この環境で ping localhost とやると

C:\WINDOWS\system32>ping localhost

DESKTOP-PC001 [::1]に ping を送信しています 32 バイトのデータ:
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms

::1 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 0ms、最大 = 0ms、平均 = 0ms

上記のような結果になり、localhost へのping は、 IPv6 での応答になっていることが分かります。

これは、IPv4よりもIPv6 が優先されているから ということなんですが、

netsh interface ipv6 show prefixpolicies コマンドを実行することで優先順位が確認できます。
(以下の結果では IPv6の通信が優先されています)

C:\WINDOWS\system32>netsh interface ipv6 show prefixpolicies
アクティブ状態を照会しています...

優先順位   ラベル  プレフィックス
----------  -----  --------------------------------
        50      0  ::1/128
        40      1  ::/0
        35      4  ::ffff:0:0/96
        30      2  2002::/16
         5      5  2001::/32
         3     13  fc00::/7
         1     11  fec0::/10
         1     12  3ffe::/16
         1      3  ::/96
プレフィックス 説明
::1/128 IPv6 ループバックアドレス
::/0 IPv6 デフォルトルート
::ffff:0:0/96 IPv4-mapped IPv6 address


IPv4を優先させる

::ffff:0:0/96 (IPv4-mapped IPv6 address) を最も優先順位が高い状態にすれば、IPv4での通信が優先されるようになります。

そのために優先順位を変更する必要があります。
管理者権限で、コマンドプロンプト(or Windows Termianl)を起動して以下を実行します。

netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 55 4
netsh interface ipv6 set prefixpolicy ::1/128 50 0
netsh interface ipv6 set prefixpolicy ::/0 40 1
netsh interface ipv6 set prefixpolicy 2002::/16 30 2
netsh interface ipv6 set prefixpolicy 2001::/32 5 5
netsh interface ipv6 set prefixpolicy fc00::/7 3 13
netsh interface ipv6 set prefixpolicy fec0::/10 1 11
netsh interface ipv6 set prefixpolicy 3ffe::/16 1 12
netsh interface ipv6 set prefixpolicy ::/96 1 3


netsh interface ipv6 show prefixpolicies コマンドを実行して優先順位が変更されていることを確認します。

C:\WINDOWS\system32>netsh interface ipv6 show prefixpolicies
アクティブ状態を照会しています...

優先順位   ラベル  プレフィックス
----------  -----  --------------------------------
        55      4  ::ffff:0:0/96
        50      0  ::1/128
        40      1  ::/0
        30      2  2002::/16
         5      5  2001::/32
         3     13  fc00::/7
         1     11  fec0::/10
         1     12  3ffe::/16
         1      3  ::/96

::ffff:0:0/96 が一番上(最優先)になっていることが分かります。


この状態で ping localhost を実行してみると以下の通り IPv4 での応答 になっていることが分かります。

C:\WINDOWS\system32>ping localhost

DESKTOP-PC001 [127.0.0.1]に ping を送信しています 32 バイトのデータ:
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128

127.0.0.1 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 0ms、最大 = 0ms、平均 = 0ms


優先順位を元に戻す

仮に優先順位を元に戻す場合は 管理者権限で netsh interface ipv6 reset を実行して PC を再起動します。


PuTTY で SSHトンネル用のポートフォワード設定

PuTTY(パティ)での、SSHトンネリングするためのポートフォワード設定方法です。

今回使用している PuTTYが ごった煮版 ではない ので、スクリーンショットは日本語表示になっていません。

以下は公開鍵認証でのssh接続をする例になっています。


前提

PuTTYで公開鍵認証でのssh接続をするためには .ppk(PuTTY形式)の秘密鍵が必要になります。

PuTTYgen を使って .pemファイル から .ppkファイルを作成しておく必要があります。
.ppkの秘密鍵作成時にパスフレーズを設定することになります。

以下は .ppkファイルは作成済みであるという前提での手順になっています。


踏み台にするサーバへのssh接続設定

踏み台用サーバへのssh接続のための設定です。通常のssh接続の設定と何も変わりません。

f:id:nini_y:20210417002354p:plain

Category : Session で以下を設定します。

  • Host Name (or IP address)
    • ssh接続する踏み台サーバのホスト名( or IPアドレス) を入力します。


f:id:nini_y:20210417002814p:plain

Category : Connection > Data で以下を設定します。

  • Auto-login username
    • ssh接続するユーザ名 を入力します。


f:id:nini_y:20210417002958p:plain

Category : Connection > SSH > Auth で以下を設定します。

  • Private key file for authentication
    • 「Browse」ボタンをクリックして、用意してある.ppkファイル を選択します。


ポートフォワード(ローカルフォワード)の設定

f:id:nini_y:20210417003755p:plain

Category : Connection > SSH > Tunnels で以下を設定します。

  • Source port
    • ローカルで待ち受けするポート を入力します
  • Destination
    • 転送先のサーバのホスト名( or IPアドレス):転送先サーバのポート を入力します

上記入力後に「Add」ボタンをクリックします。


設定内容の保存

f:id:nini_y:20210417002354p:plain

Category : Session の Saved Sessions に適当な名前を入れて「Save」ボタンをクリックします。


接続

「Open」ボタンをクリックします。

以下のような内容が表示されるので、.ppkファイルに設定したパスフレーズを入力して Enter を押します。

Using username "XXXXXX".
Authenticating with public key "imported-openssh-key"
Passphrase for key "imported-openssh-key":

これで、踏み台サーバへの接続とポート設定の待ち受けができた状態になります。

あとは、設定したローカルでの待ち受けポートへの通信を行えば、ポート転送が行われます。



関連エントリ

Windows 10 - コマンドでポートフォワード(SSHトンネル)

ここ最近の Windows 10 であれば sshポートフォワード(SSHトンネリング)するのには、 SSHクライアントソフトを別途インストールしなくても組み込みのコマンドで実行できます。

実行するコマンド (公開鍵認証でのSSHの場合)

ssh {ssh接続用ユーザ}@{踏み台サーバのホスト} -i {秘密鍵のパス} -L {待ち受けするポート}:{転送先のホスト}:{転送先ホストのポート}


具体的な実行例は以下になります。(IPアドレスやホスト名等はある程度伏せた感じにしています)

ssh user001@40.125.XXX.XX -i C:\Users\user1\privatekey.pem -L 11433:dummy-DB-***01.database.windows.net:1433

上記例でいくと以下のようになっています。

  • 踏み台とするSSHサーバ: 40.125.XXX.XX
  • ローカルで待ち受けするポート: 11433
  • SSHサーバ経由で実際に接続したいサーバ
    • ホスト: dummy-DB-***01.database.windows.net
    • ポート: 1433

この例は、Azure上のSQL Server へ SSHトンネリングして接続したい場合の設定イメージになります。


本筋とずれますが、 {秘密鍵のパス} が、ユーザディレクトリの下などではない場合、Permission denied になることがあります。
公開範囲の狭いディレクトリ(ユーザディレクトリの下)に秘密鍵は配置してください。


正常に接続できれば、ローカルでの netstat -na の結果に、待ち受けしたポートでの LISTENING の結果が含まれます。(以下)

PS C:\Users> netstat -na

アクティブな接続

  プロトコル  ローカル アドレス      外部アドレス           状態
...
  TCP         127.0.0.1:11433        0.0.0.0:0              LISTENING
...


この状態で、 locahost:11433 (or 127.0.0.1:11433) へ通信すると、
SSHトンネリングされて dummy-DB-***01.database.windows.net:1433 へ転送されます。


まとめ

Windowsでもコマンド一発でsshポートフォワードできて楽ですね。



関連エントリ