凡ジニアのtxt

エンジニアリングができない凡ジニア

FTP/FTPS/SFTPの備忘録

はじめに

FTP/FTPS/SFTPについて調べたことを忘れないための備忘録になります。

FTP

File Transfer Protocolの略であり、基本的にクライアント-サーバ間においてファイル転送を行う通信プロトコルである。

チャネル

FTPでは、ファイル転送を行うために、2つの通信用チャネルを使用して動作する。

  • 制御チャネル: ポート番号 21, 主にFTPコマンドの送受信を行うためのチャネル。
  • データチャネル: ポート番号 20, ファイルデータの送受信を行うためのチャネル。但し、パッシブモードの場合は、ランダムなポートが選出される。
モード

FTPでは、クライアント-サーバ間において、どちらに対して接続を行うかの2つのモードがある。

  • アクティブモード: サーバからクライアントに対して、データチャネル用ポートを通知して、ファイルデータの送受信を行う。
  • パッシブモード: クライアントからデータチャネル用のランダムなポート選出して、サーバへ通知し、ファイルデータの送受信を行う。

FTPS

FTP over SSL/TLSの略であり、SSL/TLSを使用してデータチャネルを送受信を暗号化する。

モード
  • 明示モード (explicit): クライアントが暗号化に使用するプロトコルを選択して、暗号化してファイル転送を行う。
  • 暗黙モード (implicit): クライアントは、サーバが使用しているプロトコルに対してのみ暗号化されたファイル転送が可能になる。

SFTP

SSH FTPの略であり、SSHで暗号化されたチャネルを用いて、安全なデータの送受信を行う。

所感

FTPを学ぶ必要があったため、FTP関連のことをまとめてみました。実際の環境に使われているファイル転送のプロトコルが、FTP/FTPS/SFTPなのか把握していないと、どのレイヤーで問題が起きているか時間がかかりそうだと思う。特にSSL/TLSSSHの場合だと、サーバ側の調査も必要になる。

参考文献

TCP/IP - FTPとは

Learn the Difference Between Implicit and Explicit FTPS

Wiresharkを使って、FTPパケットのやりとりを見よう

はじめに

FTPを使ったアプリケーションに問題があった際に、正常であるFTPの挙動を確認しました。その際に、Wiresharkを使った方法を備忘録として残してます。

docker 環境

FTP Server: stilliard/pure-ftpd

FTP Client: Ubuntu 18.04

https://hub.docker.com/r/stilliard/pure-ftpd/

docker 環境の構築

今回はFTP ServerとClientを分けて、dockerホストを2つ作成します。最初に、docker環境上でFTP Serverを構築します。

FTP Server

前述したpure-ftpdのサンプルコマンドで、docker環境上でFTP Serverを立ち上げます。

~ $ :~$ docker run -d --name ftpd_server -p 21:21 -p 30000-30009:30000-30009 -e "PUBLICHOST=localhost" stilliard/pure-ftpd

ftp-userを作成するために、先ほど作成したftpd_serverにアクセスします。

# 先ほど作成したpure-ftpdのdocker process
~ $ :~$ docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED              STATUS              PORTS                                                                                                      NAMES
7382b1acd311   stilliard/pure-ftpd   "/bin/sh -c '/run.sh…"   About a minute ago   Up About a minute   0.0.0.0:21->21/tcp, :::21->21/tcp, 0.0.0.0:30000-30009->30000-30009/tcp, :::30000-30009->30000-30009/tcp   ftpd_server

# /bin/bashを実行
~ $ :~$ docker exec -it 7382b1acd311 /bin/bash

# ftpアップロード先のディレクトリ test-ftp 作成
root@7382b1acd311:~# mkdir /home/ftpusers/test-ftp

# ftp-userの作成
# ftp-user: test-ftp
# Uplaod先:/home/ftpusers/test-ftp/
root@7382b1acd311:~# pure-pw useradd test-ftp -f /etc/pure-ftpd/passwd/pureftpd.passwd -m -u ftpuser -d /home/ftpusers/test-ftp/
Password:
Enter it again:

# ディレクトリのアクセス権の付与
root@7382b1acd311:~# chown test-ftp:ftpgroup /home/ftpusers/test-ftp/

# logout
root@7382b1acd311:~# exit

FTP Client

FTP Clientととして、docker環境上にUbuntu 18.04を起動する。

~ $ :~$ docker run -it -d --name ftpd_client ubuntu:18.04 /bin/bash

dockerが作成されたことを確認して、必要なパッケージをインストールします。今回は、ftptcpdumpだけインストールします。

~ $ :~$ docker ps -a
CONTAINER ID   IMAGE                 COMMAND                  CREATED              STATUS              PORTS                                                                                                      NAMES
b1457c177a5a   ubuntu:18.04          "/bin/bash"              About a minute ago   Up About a minute                                                                                                              ftpd_client
7382b1acd311   stilliard/pure-ftpd   "/bin/sh -c '/run.sh…"   16 minutes ago       Up 16 minutes       0.0.0.0:21->21/tcp, :::21->21/tcp, 0.0.0.0:30000-30009->30000-30009/tcp, :::30000-30009->30000-30009/tcp   ftpd_server

~ $ :~$ docker exec -it b1457c177a5a /bin/bash

# パッケージの一覧を更新
root@b1457c177a5a:/# apt-get update

# ftpのインストール
root@b1457c177a5a:/# apt-get install ftp

# tcpdumpのインストール
root@b1457c177a5a:/# apt-get install tcpdump

FTPの挙動確認

FTP Serverであるftpd_serverIPv4アドレスを確認します。そのIPv4は、FTP Clientのftpで使われるのでコピーしておきます。

~ $ :~$ docker inspect network bridge
....
        "Containers": {
            "7382b1acd3117c281148aacb75f11f1e509e128351da48094fe63d6dabff0b7c": {
                "Name": "ftpd_server",
                "EndpointID": "9906eba71be08fee78e4a7f2a09dae004db3214d375cdf86e316609fea57354a",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": "2001:db8:1::242:ac11:2/64"
            },
        },
....

後ほど、WiresharkFTPのパケットを見るので、もう1つターミナルを立ち上げて、FTP Clientにアクセスします。その後、tcpdumpによってpcapを作成します。

~ $ :~$ docker exec -it b1457c177a5a /bin/bash
# tcpdumpを使って、pcapを取得
root@b1457c177a5a:/# tcpdump -w ftp.pcap

次に、FTP Clientからテストのファイルを作成して、ftpを実行します。

# テストファイル用の作成
root@b1457c177a5a:~# echo "test" > test.txt

# FTPの実行
root@b1457c177a5a:~# ftp 172.17.0.2
Connected to 172.17.0.2.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 5 allowed.
220-Local time is now 06:22. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (172.17.0.2:root): test-ftp
331 User test-ftp OK. Password required
Password:
230 OK. Current directory is /
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put test.txt
local: test.txt remote: test.txt
200 PORT command successful
150 Connecting to port 33289
226-File successfully transferred
226 0.001 seconds (measured here), 9.30 Kbytes per second
5 bytes sent in 0.00 secs (28.2243 kB/s)
ftp> exit
221-Goodbye. You uploaded 1 and downloaded 0 kbytes.
221 Logout.

FTP Serverでtest.txtがアップロードされていることを、以下のコマンドで確認します。

# テストファイルがアップロードされているか確認
root@7382b1acd311:/# ls /home/ftpusers/test-ftp/
test.txt

最後に、docker環境内において、FTPのパケットが保存されたftp.pcaplocalhostへコピーします。

# localhostにpcapのコピー
~ $ :~$ docker cp b1457c177a5a:ftp.pcap ~/Desktop

Wiresharkを使った挙動の確認

今回は、下図に流れに沿ってFTPの挙動を確認します。

  1. FTP ClientがFTP ServerのPort 21へ接続要求を行う

  2. FTP ServerがFTP Clientに対して、TCP接続を行う

  3. FTP Serverがデータコネクション用のPort 20を通知

  4. FTP ClientがFTP ServerのPort 20へファイルを送信

f:id:aki5151:20211019110109p:plain

WiresharkFTPパケットのやりとりを表示したのが、下図になります。

f:id:aki5151:20211019110124p:plain

所感

実運用において問題が発生した際に、正常な通信の挙動を把握していないと、どのプロセス段階で問題が起きているが把握出来なかった。今回、Wiresharkを使ってFTPの正常な挙動を確認してみた。このようなことを積み重ねさえすれば、トラブルシューティングのノウハウの土台となるはずである。

参考文献

【Docker】FTPサーバコンテナ構築手順と使い方(Pure-ftpd Server) | インフラエンジニアの技術LOG

Docker Hub

「Training Site Reliability Engineers: What Your Organization Needs to Create a Learning Program」を読んでみた

はじめに

先日のSRE Gapsを視聴して、Googleが無料で公開しているSREに関するドキュメントがあることを知った。その中で「Training Site Reliability Engineers: What Your Organization Needs to Create a Learning Program」というドキュメントがあったので、読んだ。本ドキュメントで気になった部分だけ、感想を書いてます。

より詳細を見たい方は、以下参照してください。

sre.google

Training Site Reliability Engineers: What Your Organization Needs to Create a Learning Programとは

GoogleのSRE教育チームがどのようにSREを教育していった方がいいのかを事細かに説明している。例えば、

などが説明されている。

SREトレーニング技術

以下、大まかに5つのレベルで説明されている。日本語訳は、主観的でイメージがわきやすいように翻訳してます。

レーニングをする労力が上に位置するほど低くなり、下に位置するほど高くなる。

Sink or Swim: 一か八か

これはチームに新しく入ってきたメンバー自身に対して、資料やトレーニングプログラムを持たずに物事を学んでもらう方法が当てはまると思う。最も労力が少ないが、ストレスがたまり、自信がつかない方法(Imposter syndrome)でもある。日本の企業だと、現場に入れた後、放置プレイで仕事してもらう方法に当てはまることができる(通称、OJT)。

Self-Study: 自己学習

メンバーに学んでもらいたい項目をチェックリストでまとめて、提供する方法。各項目の学習媒体としては、ドキュメント、ビデオ、技術演習などである。しかし、技術が古くなり、内容のメンテナンスする必要が出てくる。またメンテナンスを怠ると、メンバーに対して学習時間の無駄な浪費につながる。

Buddy System: ペアプロやペアトラブルシューティング

オンコールなどの実務に対して、経験者とメンバーでペアを組んで取り組む方法である。この際に、Self-Studyで使われた学習媒体とつけ合わせてすることで、より効率的な学習方法になると言われている。

Ad Hoc Classes: チーム単位によるディスカッション

指導者と小さなチームが参加したディスカッション方法である。この際に、ホワイトボードを使い、システム図などを描写しながら、ディスカッションをすることで、より効果的な学習に繋がる。新しいメンバーに既存のメンバーでさえ知らない最新の技術やトピックを学んでもらうことにより、全体的なチームの底上げにも繋がる。

Systematic Training Program: 組織的なトレーニングプログラム

モニタリング、インシデント対応、ポストモーテムの作成などの実務により近い形で学ぶトレーニング方法であり、最も労力がかかる。

所感

新メンバーにどうやって学んでもらうか悩んでいたことがあったが、個人としてBuddy Systemまで対応できると思えた。Ad Hoc ClassesやSystematic Training Programにおいて、組織的に動く必要があるので、マネージャークラスが考慮することだと思えた。しかし、トレーニングもエンジニアリングの必要不可欠な要素なので、今後のキャリアのために、頭の隅に入れておくと役に立つのかもしれない。

AWS DBサービス集

ざっくりとした概要

サービス名 概要
RDS AWSが提供するマネージド型のリレーショナルデータベースのサービス。エンジンのタイプとして、MySQL/SQL serer/Amazon Auroraなどが提供されている。
Amazon Aurora AWSが提供する分散型のリレーショナルデータベースのサービス。分散高速処理を持つNoSQLと容易のデータ操作性を持つRDBの両方の特徴を持っている。またMySQLPostgreSQLとの互換性も持っている。
DynamoDB AWSが提供するマネージド型のNoSQLデータベースのサービス。キーバリューで、結果整合性モデルを採用されている。ユーザー行動/セッション情報などのデータやログ管理に向いている。
Kinesis AWSが提供するIoTやSNSなどのビックデータに対するストリームデータ処理用のサービス。ストリーミンデータ処理として、Apach Kafkaと同様な立ち位置である。
Redshift AWSが提供するデータウェアハウス(DWH)向けの分散・高速処理を可能としたリレーショナルデータベースのサービス。データの抽出や集約に特化したBIデータ分析用の用途として用いられる。
ElastiCache AWSが提供する高速なRead/Writeが可能なインメモリキャッシュ型DBのサービス。種類として、RedisとMemcachedが提供されている。

RedisとMemcahcedの違い

Redis Memcached
スナップショット機能がある スナップショット機能がない
永続化可能 永続化不可能
フェイルオーバーや復元可能 フェイルオーバーや復元不可能

勉強用 AWS VPCリソースのメモ

AWS VPCリソースのメモ

以下でまとめたAWSサービスの中、VPCの各リソースの概要をまとめた表になります。

aki5151.hateblo.jp

AWS VPCリソース

VPC リソース名 区分 概要
サブネット VPC AWSの仮想ネットワークに対して、論理的にネットワークを分離することができるリソース。インターネットゲートウェイに対して接続されているサブネットをパブリックサブネットワークと呼び、それに接続されていないサブネットをプライベートサブネットワークと呼ぶ。
ルートテーブル VPC サブネットまたはゲートウェイからのネットワークトラフィックの経路を決定する(ルーティング)。一般的なロードバランサーのルーティングテーブルにイメージが近いと思われる。
インターネットゲートウェイ VPC インターネットから流れてきたトラフィックAWSのサービスにルーティングするリソース。
Egress Only インターネットゲートウェイ VPC 上記のインターネットゲートウェイに対して、IPv6に対応したリソース。
キャリアゲートウェイ VPC 5G用のWavelengthゾーンに対して接続するゲートウェイのリソース。
DHCPオプションセット VPC VPC内のインスタンスに対して、DNS/NTPなどのサービスを提供するリソース。デフォルトでは、ip-**-**-**-**のようなホスト名を提供している。
Elastic IP VPC インターネットからアクセス可能なパブプリックIPv4を提供するリソース。
マネージドプレフィックスリスト VPC 特定のサブネットのCIDRをセットできるリソース。
エンドポイント VPC AWSの他リージョンのVPCと接続できるリソース。
NATゲートウェイ VPC プライベートIPとパブリックIPを変換するリソース。返信用トラフィックのために使用される。
ピアリング接続 VPC プライベートサブネットワークに属するインスタンス同士を1対1でプライベートなトラフィックの通信を行うことができるリソース。DR(Disaster Ricovery)構成などを行いたい時に使用する。
ネットワークACL セキュリティ VPC/サブネットに対して、インバウンドとアウトバウンドのトラフィックに対して通信制御するファイアウォールのリソース。
セキュリティグループ セキュリティ EC2インスタンスが属するVPCの仮想的なファイアウォール。インバウンド(Ingress)とアウトバウンド(Egress)へのリク
Transit Gateway Transit Gateway 。複数の他VPCに接続するリソース。ピアリング接続は1対1での静的な接続になるが、Transit Gatewayでは動的に複数の他VPCトラフィックの通信を可能にする。

外部からcurlを用いてk8sリソースにアクセスする

はじめに

外部からKuberernetes(以下、k8s)のリソースにアクセスしたいことがあったりします。特にcurlを用いたリクエストの送信やgo/pythonなどを使った自動化など。今回はcurlを使ったリクエストの送信方法をまとめています。

実装

必要となるk8sリソース

k8sリソースを外部からリクエストを送る場合、以下のリソースを設定する必要があります。

  • service account
  • secret
  • clusterrole
  • clusterrolebinding

以下、上記のk8sリソースの関係図になります。 f:id:aki5151:20210819205823j:plain

service accountとsecretの作成

最初に、system userのようにPodなどに任意の処理させる用のアカウントとしてservice accountを作成します。またservice accountを作成した場合、secretは自動的に作成されます。

# service accountのyamlを作成
$ kubectl create sa test-sa --dry-run=client -o yaml > test-sa.yaml
$ cat test-sa.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: test-sa

# test-saを作成
$ kubectl apply -f test-sa.yaml
serviceaccount/test-sa created

# test-saを確認
$ kubectl get sa
NAME        SECRETS   AGE
default     1         1d
test-sa     1         23s

# test-saのsecretを確認
$ kubectl get secret
NAME                    TYPE                                  DATA   AGE
default-token-nm8bq     kubernetes.io/service-account-token   3      1d
test-sa-token-jrmqf     kubernetes.io/service-account-token   3      58s

clusterroleの作成

デフォルトで作成されているclusterroleのadminを使用するので、任意のclusterroleは作成しません。

clusterrolebindingの作成

先ほど作成したservice accontとclusterroleを紐づけるために、clusterrolebindingを作成します。

# clusterrolebindingのyamlを作成
$ kubectl  create clusterrolebinding test-clusterrolebindng --clusterrole=test-clusterrole --dry-run=client --serviceaccount=default:test-sa -o yaml > test-clusterrolebindng.yaml

$ cat test-clusterrolebindng.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: test-clusterrolebindng
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admin
subjects:
- kind: ServiceAccount
  name: test-sa
  namespace: default

#  test-clusterrolebindngを作成
$ kubectl apply -f test-clusterrolebindng.yaml
clusterrolebinding.rbac.authorization.k8s.io/test-clusterrolebindng created

#  test-clusterrolebindngを確認
$ kubectl get clusterrolebinding test-clusterrolebindng
NAME                     AGE
test-clusterrolebindng   53s

外部からcurlのリクエストを送信

外部からcurlを用いて、httpsリクエストを送信できるk8sリソースの準備ができました。リクエストを送信するのには、service accountのsecretにあるTOKENが必要になります。以下のように環境変数を定義してからリクエストを送信します。

$export TOKEN=`(kubectl get secret test-sa-token-jrmqf -o json | jq -r .data.token |  base64 -d)`

$ curl -g -H "Content-Type:application/json" --header "Authorization: Bearer $TOKEN" --insecure "https://$apiserver_ip:$apiserver_port/api/v1/namespaces/default/configmaps"
{
  "kind": "ConfigMapList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces/default/configmaps",
    "resourceVersion": "35090648"
  },
  "items": []
}

これでk8sから、レスポンスが返ってきたことがわかります。

所感

本記事で扱ったk8sリソースの理解不足があったりしたので、まとめてみました。意外と勉強になったなと思います。

勉強用 AWSサービスのメモ

AWSサービスのメモ

AWSの各サービスを勉強している中で、概要をまとめた表になります。

大枠なAWSサービス

サービス名 概要
EC2 (Elastic Compute Cloud) AWSの最も基本的なサービス。OS/Memory/CPU/Storageなどの設定が可能。イメージ的にはVirtual Machine(VM)やOpenStackのCompute Nodeに近い。EKSを用いた場合はContainerのInstanceになると思われる。
EKS (Elastic Kubernetes Service) AWSが提供するKubernetesのアプリケーションを実行するサービス。役割としては、KubernetesのMaster Nodesを担っている。AWS公式では、Controle Planeとも呼ばれている。
S3 (Simple Could Service) AWSが提供するオンラインストレージ。EC2に直接アタッチすることはできない。
CloudFormation AWSが提供するAWS自身が提供するサービスに対して、Infrastructure as Code(IaC)によってモデリングするサービス。
ACM (AWS Certificate Manager) AWSが提供する証明書(SSL/TLS)を管理するサービス。AWSで作ったWebサービス等に、HTTPS通信を使いたい場合などに使う。
EBS (Elastic Block Store) AWSが提供するブロックストレージサービス。EC2から直接アタッチすることが可能。EKSにおいて、PV(Persistent Volume)として使用する。
CodePipeline AWSが提供する継続的デリバリー(Continuous Delivery: CD)。アプリケーションの構築、テスト、デプロイを自動化する。またGitHubやサードバーティのサービスとのプラグインがある。
Fargate AWSが提供するEKSのData Plane。いわゆる、KubernetesにおけるWorker Nodeにあたる。EC2とは違って、DataPlaneであるVMのシステム運用管理が不要となる。しかし、VMへのアクセスができないため、DataPlaneの拡張性が乏しいことやモニタリングへの制限があると思われる。
IAM (Identity and Access Management) AWSが提供するユーザーの認証・認可するサービス。
CloudWatch AWSが提供する各サービスを可視化するモニタリングシステム。またlogの収集・保存やアラートの送信も可能。
CloudFront AWSが提供するCDN (Contents Delivery Network)サービス。Javascriptのみで開発可能。
Lambda AWSが提供するサーバレスな環境でプログラムが実行できるサービス。特定の言語で開発可能。
CloudTrail AWSアカウントによる操作やAPIのログを保存するサービス。一定の通信量まではの料金は無料。
DirectConnect オンプレ環境から物理的にAWS環境に接続する専用線サービス。
Route 53 AWSが提供するDNSサービス。

CDN: Webサービス配信の大元となるオリジンサーバーの負荷を軽減するために、ユーザーの近くにキャッシュサーバー(エッジサーバー)を配置したネットワーク構成。これにより、従来のオリジンサーバーの負荷が軽減され、ユーザーへの応答処理を向上させる。

参照: CDNで機会損失を回避!CDNの仕組みから導入効果の試算まで分かりやすくご紹介 | さくらのナレッジ

AWS VPCリソース

AWS VPCリソース - 凡ジニアのtxt

所感

AWS/GCP/Azureなどのクラウドサービスが発展している中、一つでも自己学習しとけば役に立つかな程度でまとめています。また各サービスを勉強する都度、表を更新する予定です。
CloudFormationとよく比較されているTerraformがあり、自由度が高いらしいのでチャレンジしてみたい。CloudFormationは、一度構築したら削除して、再定義する必要あるらしく、ユースケースによっては使い分けれた方がいいのかもしれない。