WindowsのOpenSSHでGitサーバーを立ち上げる

# はじめに
Git for Windowsにはsshdが添付されてるのでそのままサーバーとして運用出来る・・・はずなんですが情報も少ないし面倒な割にサービス起動出来ないなど制約も多い
WindowsにはOpenSSHが用意されていますのでこっちでサーバーを立ち上げた方が潰しが利くかな、ということでやってみた備忘録です

自分のメモ用なので他の環境では違う可能性があるのはご承知おきください_○□=

# メリット
- Windowsなので気軽にGitサーバーの立ち上げが出来る
- OpenSSHを使うことで潰しが利く・・・かも？
- 容量がいっぱい使える（gitの商業サービスは容量制限がキツい）

# デメリット
- Githubのような商業サービスで出来る高度なことはほとんど出来ない
- OpenSSHでデフォルトシェルをbashに切り替えるので他の理由でsshにログインするときもbashを使用することになります:innocent:
- SSHアクセス時のShellをBashにしてしまうので、Git以外でログインのときもBashを使うことに・・・
- 不正アクセス等の対策も別途考えないと大変なことに

# 準備
今回環境＆使用したものです

- Windows7(32bit)
- Git for Windows Ver2.27.0 32bit　[[https://gitforwindows.org/]](https://gitforwindows.org/)
- OpenSSH Win32 v8.1.0.0p1 　[[https://github.com/PowerShell/Win32-OpenSSH/releases]](https://github.com/PowerShell/Win32-OpenSSH/releases)
    - 最近のWindowsでは
  「設定」→「アプリ」→「アプリと機能」→「オプション機能の管理」→「＋機能の追加」で「OpenSSHサーバー」を選択することでもインストール出来ます

# 設定方法
## 1)Gitのインストール
- Gitのインストール
大体はデフォルトのままでOKなので割愛します<br>
ただし一つ注意点として、現在のバージョンではアルファベット以外のユーザー名に問題が生じることがあるようです<br>
その場合には"Configuring the terminal emulator to use with Git Bash"で"Use Windows'default console window"を選ぶ必要があります
![GitInstall_termial emulator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659544/a40298da-bd59-7e48-0e02-752b6d3d49cd.png)


- Pathの設定
環境変数`Path`にGitのフォルダを追加します
![環境変数Pathの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659544/3e40d226-61c2-c5a0-2b9f-4ab68e477051.png)

```
C:\Program Files\Git\cmd
C:\Program Files\Git\usr\bin
C:\Program Files\Git\bin
C:\Program Files\Git\mingw64\bin
C:\Program Files\Git\mingw64\libexec\git-core
```
## 2)OpenSSHのインストール
- 配置
上のリンクからダウンロードした場合zipにそのまま固まっていますので、OpenSSH用のフォルダ`C:\OpenSSH`を作り展開します
![OpenSSHFolder](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659544/98952d04-7f4a-f7c4-318a-6cb866b78736.png)


- Pathの設定
環境変数`Path`にOpenSSHのフォルダを追加します

```
C:\OpenSSH\
```

- PowerShellを管理者特権で起動し、スクリプトの起動制限を解除<br>
スクリプトを使用するので起動制限を解除します。危険なので後で制限復帰をするのを忘れずに！

```ruby:PowerShell
PS c:\> Set-ExecutionPolicy Bypass                 //スクリプトの制限解除

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピックで説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"):Y

PS c:\> Get-ExecutionPolicy                       //ちゃんと設定出来たか確認
Bypass                                            //Bypass:確認なしにすべてのスクリプトを実行
```
- sshのインストールスクリプトを実行する

```ruby:PowerShell
PS C:\OpenSSH> .\install-sshd.ps1
[SC] SetServiceObjectSecurity SUCCESS
[SC] ChangeServiceConfig SUCCESS
[SC] ChangeServiceConfig2 SUCCESS
sshd and ssh-agent services successfully installed
```
- ポートの開放<br>
 ここでは`ポート22`を開放してます、変更する場合は他の値にします<br>
 ちなみに22にするとエラい勢いで知らないところからアクセスされます。変更おすすめ

```ruby:PowerShell
PS C:\> New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
PS C:\> netsh advfirewall firewall add rule name=sshd dir=in action=allow protocol=TCP localport=22
```

- パーミッションの変更<br>
OpenSSHではパーミッションが重要になります。スクリプトがあるので任せましょう（最初手動でやって失敗した(汗）<br>
ユーザーを新しく作ったり関連する部分のパーミッションを弄った場合でsshが上手く動かなかった時にもこのスクリプトを使います

```ruby:PowerShell
PS C:\OpenSSH> .\FixHostFilePermissions.ps1
```

- スクリプトの起動制限を復帰

```ruby:PowerShell
PS c:\>Set-ExecutionPolicy Restricted            //スクリプトの制限復帰

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピックで説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"):Y

PS c:\>Get-ExecutionPolicy                       //ちゃんと設定出来たか確認
Restricted                                       //Restricted:すべてのスクリプトを制限
```

- サービスの自動起動の設定

```ruby:PowerShell
PS C:\> Set-Service sshd -StartupType Automatic       //自動起動の設定
```

- サービスの起動と再起動<br>
sshdを起動・再起動したい場合のコマンド

```ruby:PowerShell
PS C:\> net start sshd                                //起動
PS C:\> restart-service sshd                          //再起動
```

## 3)Gitにアクセスするユーザーアカウントの作成と設定
- ユーザーアカウントの作成
Gitで使用するユーザーアカウントを作成する
![CreateUser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659544/25b75c3f-30a7-ed9a-d7b3-19adbf0baa49.png)
(ここでは`GitUser`というアカウントを作成しています)


- Gitのglobal情報の設定
Gitのグローバル情報を設定する(globalは各ユーザーごとに管理される設定です)

```ruby:PowerShell(ユーザーアカウントが"GitUser"の場合)
PS C:\Users\GitUser> git config --global user.name "username"                  //利用者情報（名前）
PS C:\Users\GitUser> git config --global user.email "username@mymailserver.jp" //利用者情報（メールアドレス）
PS C:\Users\GitUser> git config --global core.quotepath false                  //日本語を表示するための設定
PS C:\Users\GitUser> git config --global sendpack.sideband false               //gitプロトコルでpushするとハングアップすることがあるのを防止
```

- SSH用フォルダの作成
 - SSH用のユーザー個別フォルダ`c:\Users\ユーザーアカウント\.ssh`フォルダを作成します

```ruby:PowerShell(ユーザーアカウントが"GitUser"の場合)
PS C:\Users\GitUser> mkdir .ssh
```

- SSH鍵の作成

```ruby:PowerShell(ユーザーアカウントが"GitUser"の場合)
PS C:\Users\GitUser> ssh-keygen -t rsa -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\GitUser/.ssh/id_rsa):        //作成ファイル名の指定:(規定値ならそのままEnter)
Enter passphrase (empty for no passphrase):                                //パスフレーズの指定:(不要ならそのままEnter)
Enter same passphrase again:                                               //パスフレーズの再確認
```
(この方法でrsa形式で鍵長2048byteの秘密鍵ファイル`id_rsa`と公開鍵ファイル`id_rsa.pub`の2ファイルが作成されます。セキュリティ的に不安であれば形式を変えたり鍵長を長くするなど出来ます。詳細は他の詳しいサイトを参考にしてください)


- SSH公開鍵の設定
 - SSH用のユーザー個別フォルダ`c:\Users\ユーザーアカウント\.ssh`フォルダに公開鍵を設定します

```ruby:PowerShell(ユーザーアカウントが"GitUser"の場合)
PS C:\Users\GitUser\.ssh> cat id_rsa.pub >> authorized_keys
```
- SSH設定ファイル`sshd_config`の変更<br>
`C:\ProgramData\ssh\sshd_config`にあるSSHの設定ファイルを変更します

```
Port 22                            //ポート番号
PasswordAuthentication no          //パスワード認証：不許可（これをしないと折角鍵認証を設定してもパスワードで入れてしまう）
```

- パーミッションの変更<br>
PowerShellにてスクリプトの実行を許可した後、OpenSSHで使用したパーミッション修正スクリプトを再度実行する

```ruby:PowerShell
PS C:\OpenSSH> .\FixHostFilePermissions.ps1 -Confirm:$false
```
- デフォルトシェルをBashに変更<br>
シェルをBashに変更しないとGitのコマンドが上手く動きません

```ruby:PowerShell
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\Git\bin\bash.exe" -PropertyType String -Force 
```

- 動作確認
  - OpenSSH動作確認<br>
クライアント側からSSHでリモートログインしてみる<br>
<br>
PowerShellからリモートログインしてみて接続出来れば成功です。<br>
`ssh.exe -i id_rsa GitUser@ServerName -p 22`<br>
　　　　id_rsa : 秘密鍵<br>
　　　　GitUser : アクセスユーザー名<br>
　　　　ServerName : サーバー名もしくはサーバーのIPアドレス<br>
　　　　22 : SSHポート番号<br>
　<br>

  - Git動作確認<br>
クライアント側からGitコマンドで操作してみる<br>
<br>
Commandラインから以下のようなgitコマンドを使用し正常に終了すれば成功です<br>
`git clone ssh://GitUser@ServerName:22/c/repos/sample.git`<br>
　　　　GitUser : アクセスユーザー名<br>
　　　　ServerName : サーバー名もしくはサーバーのIPアドレス<br>
　　　　22 : SSHポート番号<br>
　　　　c/repos/sample.git : サーバーのGitリポジトリの場所(最初のcはドライブ)<br>

# おわりに
サーバーの設定は以上です

えーとここまでやっておいてなんですが、出来れば商業サービス使った方が楽だと思います（＾＾；
今回はいくつかの事情により難しいと判断した故の苦肉の策ですので

それと趣旨が変わるので今回は書かなかったのですがセキュリティ面でも上記だけではダメなのでしっかり追加対処しましょう！

# 参考

- ASCII.jp:マイクロソフト版OpenSSHをサーバーとして動作させる　[[https://ascii.jp/elem/000/001/573/1573187/]](https://ascii.jp/elem/000/001/573/1573187/)
- Windows10でSSHサーバーを立ててデフォルトシェルをBashにする　[[https://qiita.com/kenji0x02/items/3f4e7262e6de0d8c8702]](https://qiita.com/kenji0x02/items/3f4e7262e6de0d8c8702)
- 【ﾁｪｼｬわら】PowerShellとは、から学ぶ入門者の教科書-脱コマンドプロンプト　[[https://cheshire-wara.com/powershell/ps-cmdlets/sequrity/get-executionpolicy/]](https://cheshire-wara.com/powershell/ps-cmdlets/sequrity/get-executionpolicy/)
- LinuxサーバがないけどGitサーバを運用したい場合の対処法　[[https://imamachi-n.hatenablog.com/entry/2018/06/09/170331]](https://imamachi-n.hatenablog.com/entry/2018/06/09/170331)