魔術師見習いのノート

プロフィール

魔術師見習い
Author魔術師見習い-_-.
Twitter魔術師見習い

コンピュータ関係のメモを主に書きます.

MENU

コンピュータ・ネットワーク(6) -アプリケーション層-

投稿日:
修正日:
タグ:

目次

アプリケーション層は、OSI参照モデルや5階層TCP/IPモデル、4階層TCP/IPモデルなどで最も上位の層である。

アプリケーション層
トランスポート層
ネットワーク層
データリンク層
物理層
本稿では、アプリケーション層のいくつかのプロトコルによって実装されるWebや電子メールについて紹介する。

ポート番号

5階層TCP/IPモデルでは、アプリケーション層の各プロトコルはトランスポート層で提供されるポートを利用する。そして、いくつかの有名なプロトコルでは、サーバで利用するポート番号がICANNによって標準化されている。また、それ以外の多くのプロトコルも使用するポート番号が明示されている。

ウェルノウンポート番号(well-known ports)0-1023ICANNで登録されているポート番号の範囲のうち有名なもの
登録済みポート番号1024-49151ICANNで登録されているポート番号の範囲
プライベート(ダイナミック)ポート番号49152-65535 ユーザやアプリケーションが自由に利用できるポート番号の範囲。多くの場合、クライアントアプリが必要に応じて動的に使用する。

ウェルノウンポート番号(0-1023)

TCP/UDPポート番号プロトコル名機能サーバ例クライアント例
TCP,UDP7ECHO 基本的にテスト用途で使用される。送られたデータをそのまま返す
TCP20FTPFile Transfer Protocolファイル送受信のためのプロトコル。データ転送用
  • Webブラウザ
  • ftp
TCP21ファイル送受信のためのプロトコル。制御用
TCP22SSHSecure SHell暗号や認証技術を用いた安全な通信やリモートログインのためのプロトコル。
  • OpenSSH Server
  • OpenSSH Client
TCP,UDP25SMTPSimple Mail Transfer Protocol電子メールの送受信に使用するプロトコル。
  • qmail
  • sendmail
  • thunderbird
  • Microsoft Outlook
TCP,UDP42WINSWindows Internet Naming Service Microsoft Windowsネットワーク上のコンピュータ名をIPアドレスに変換するためのプロトコル。宛先不明のため、クライアントはブロードキャストで問い合わせを行う。
TCP43WHOISドメイン名やIPアドレスなどの所有者情報を取得するためのプロトコル。
  • whois
TCP,UDP53DNSDomain Name System IPアドレスとドメイン名の対応情報を取得するためのプロトコル。
  • BIND
  • Djbdns
  • nslookup
  • dig
TCP,UDP80HTTPHyperText Transfer Protocol HTMLや画像、テキストなどの送受信のためのプロトコル。 Webサーバ
  • apache
  • IIS
Webブラウザ
  • Internet Explorer
  • Google Chrome
UDP123NTPNetwork Time Protocolマシンの時間を同期するためのプロトコル。
  • ntpdate
TCP443HTTP over SSLSSL通信を用いたSMTP
TCP465SMTP over SSLSSL通信を用いたSMTP

登録済みポート番号(1024-49151)

TCP/UDPポート番号プロトコル名機能サーバ例クライアント例
TCP,UDP1194OpenVPNオープンソースのVirtual Private Networkソフトウェアのためのプロトコル。
TCP,UDP1293IPSecInternet Protocol SecurityIPパケット単位でのデータ改ざん防止や秘匿機能を提供するためのプロトコル。
TCP,UDP3389RDPRemote Desktop ProtocolMicrosoftが開発しているリモートデスクトップサービスのためのプロトコル。
  • リモートデスクトップ接続
TCP,UDP5900VNCVirtual Network Computingリモートデスクトップ方式のためのプロトコル。
TCP6000X11ネットワーク経由でXを利用するためのプロトコル。
UDP6001
TCP8080HTTPの代替HTTPのプロキシサーバやキャッシュサーバなどに使用される。

プライベート(ダイナミック)ポート番号(49152-65535)

多くのプロトコルでは、クライアントアプリケーションが使用するポート番号は、プライベートポート番号の中で使われていないもの無作為に動的に使用する。例えば、WebブラウザでHTTP(80番ポート)のサイトにアクセスする際のパケット解析した結果の一部を示す。

user% tcpdump -n -X dst port 443 -i wlan0
06:29:52.791584 IP 192.168.1.14.60063 > 183.77.202.242.80: Flags
[S], seq 1904628341, win 14600, options [mss 1460,sackOK,TS val
104657554 ecr 0,nop,wscale 4], length 0
この解析後すぐにサーバとクライアントのTCPポートを確認すると、それぞれ次のような結果となる。
サーバ
uesr% telnet 183.77.202.242 80
Trying 183.77.202.242...
Connected to 183.77.202.242.
Escape character is '^]'.
クライアント
uesr% telnet localhost 60063
Trying ::1...
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
このようにクライアントのポートは、動的に使用される。

また、同じクライアントアプリを起動し直して再度同じページにアクセスしてもクライアントが使用するポート番号が同じであるとは限らない。

user% tcpdump -n -X dst port 443 -i wlan0
06:34:15.218947 IP 192.168.1.14.60082 > 183.77.202.242.80: Flags
[F.], seq 2386135769, ack 94445475, win 2641, options [nop,nop,TS val
104723161 ecr 2033111718], length 0
前の例では、クライアントアプリは60063番ポートを使用したが、今回は60082番ポートを使用している。このように、クライアントアプリは、49152番から65535番のポート番号を動的に使用する。

TCP

トランスポート層のTCPは、高品質なデータ通信を可能にする。アプリケーション層では、これを利用したものがいくつもある。それらはユーザに対して、さまざまなものを提供する。

  • テキスト
  • メッセージ
  • 音声
  • 動画

telnet

telnetコマンドを使用すると、ユーザは簡単にTCPのサービスを受けることができる。telnetは指定したIPアドレスのポート番号に対し、ユーザが入力した文字列を送信する。本稿では、これを利用してHTTPやSMTP、POP3などのプロトコルを説明する。


Web(HTTP)

WWW(World Wide Web)上でテキストや画像などのデータを通信するのに使用されている代表的なプロトコルが、HTTP(Hyper Text Transfer Protocol)である。HTTPサーバは基本的にTCPポートの80番を使用し、クライアントが要求したテキストや画像などを送信する。HTTPクライアントとして最も有名なアプリケーションがWebブラウザである。Webブラウザにはさまざまな種類がある。

  • Internet Explorer
  • Firefox
  • Google Chrome
  • Safari

ユーザの中にはWebブラウザが表示したWebページを、Web(HTTP)サーバが提供している画面だと認識しているかもしれない。しかしHTTPクライアントが取得するデータは、基本的にHTML(Hyper Text Markup Language)という形式のテキストである。HTTPのバージョン1.0では、クライアントは次のようにGETメソッドを使用してHTMLテキストを取得できる。

user% telnet pied-piper.net 80
Trying ::1...
Connected to pied-piper.net.
Escape character is '^]'.
GET /index.html HTTP/1.0

HTTP/1.1 200 OK
Date: Mon, 14 Apr 2014 15:34:24 GMT
Server: Apache/2.2.22 (Debian)
Last-Modified: Sat, 21 Sep 2013 17:22:33 GMT
ETag: "6a2c55-b1-4e6e8084eb7e3"
Accept-Ranges: bytes
Content-Length: 177
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=UTF-8

<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added,
      yet.</p>
</body></html>
Connection closed by foreign host.
HTTPの仕様についてはRFCを参照されたし。
バージョンRFC
HTTP/1.0RFC 1945
HTTP/1.1RFC 2616

HTML(Hyper Text Markup Language)

HTTPは基本的にHTMLという形式のテキストを転送する。HTMLはマークアップ言語とよばれるコンピュータ言語の一種である。マークアップ言語はタグという文字列を使って、各文章を意味付けできる。例えば<h1>ハロー</h1>は"ハロー"という文字列が文中の最大レベルの見出しであることを示す。タグは基本的にマークしたい文字列を囲うことで意味付けする。以下にサンプルコードを示す。

<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added,
      yet.</p>
</body></html>
<html>-</html>
HTMLの文
<body>-</body>
本文
<h1>-</h1>
見出し レベル1-6(1が最大)
<p>-</p>
段落

HTMLレンダリングエンジン

WebブラウザはHTMLを受け取るとそれを読み込み、解釈してユーザに分かりやすい形で表現する。前述で紹介したWebブラウザの場合、HTMLを視覚的に見やすい形で表現する。前述のサンプルを表現した例が次の通りである。

HTML Rendering Engine
ただし必ずしも視覚的な表現だけとは限らず、視覚障害者用の音声ブラウザのように音声で表現するものもある。このHTMLを取得し、それを解釈してユーザに分かりやすいよう表現するプログラム、または機能をHTMLレンダリングエンジンという。最近のHTMLレンダリングエンジンの多くはHTMLだけでなく、CSS(Cascading Style Sheets)JavaScriptなどを読み込む機能を持つ。
CSS(Cascading Style Sheets)
HTMLの視覚的情報を指定する情報。例えば文字の色や大きさなどがある。
JavaScript
動的なWebサイトを構築するためのプログラミング言語。HTTPのクライアントであるWebブラウザによって読み込まれ、処理される。
HTMLレンダリングエンジンには、次のようなものがある。
HTMLレンダリングエンジンWebブラウザ
Trident
  • Internet Explorer
  • Sleipnir
  • Craving Explorer
Gecko
  • Firefox
  • Epiphany(後にWebKitに移行)
WebKit
  • Google Chrome
  • Safari
HTMLには基本的に視覚的情報がない。また、HTMLレンダリングエンジンによって独自のCSSのプロパティがある。それゆえ、HTMLレンダリングエンジン毎に表示される画面が同じであるとは限らない。

WebKitライブラリ

オープンソースのHTMLレンダリングエンジンであるWebKitを使用したプログラミングのサンプルを以下に示す。

#!/usr/bin/python2.7

import gtk
import webkit

win = gtk.Window()
web = webkit.WebView()
web.open("http://www.google.co.jp")
win.add(web)
win.show_all()
Debian7.10では"python-webkit-dev"というパッケージをインストールすることで、環境を整えることができる。


電子メール(SMTP, POP3)

電子メールとは、コンピュータネットワークを使って、メッセージやファイルなどのデータの送受信を行う手段のこと。電子メールはメールやEメールなどと略される。本稿ではメールと記述する。

メールの機能は、メールサーバメールクライアントによって実装される。

メールクライアント
ユーザはメールクライアントによってメールサービスを受けることができる。メールクライアントの機能は、メールサーバに保存されているメールを受け取ったり、メールサーバに頼んでメールを送ってもらったりする。
メールサーバ
メールの転送は各メールサーバが行う。

メールの送信から受信までの流れ

メールの実装にはアプリケーション層のいくつかのプロトコルが使用される。

プロトコル機能ポート
POP3(Post Office Protocol version3)メールサーバからメールを受け取る(POPとIMAPそれぞれに利点と欠点がある)。tcp/110
IMAP(Internet Message Access Protocol)tcp/143, tcp/220
SMTP(Simple Mail Transfer Protocol)メールを転送する。tcp/25
あるユーザがメールを送信し、別のユーザがメールを確認するまでの流れは次の通りである。
メールサーバは、それぞれドメイン(例:pied-piper.net)を持つ。
  1. メールクライアントはSMTPクライアントとして、自身のドメインのメールサーバのSMTPサーバ機能に対して、送信要求を行う。
  2. SMTPサーバはメールの宛先が自身のドメインであれば、設定されたメールボックスにそれを追加する。それ以外の場合、その宛先ドメインのメールサーバのSMTPサーバ機能に対し、SMTPクライアントとして送信要求を行う。
  3. 受信するユーザは、POP3やIMAPクライアントでメールサーバにアクセスすることで、自身宛に届いたメールを受け取ることができる。

電子メールの仕組み

メールは5つのプログラム(機能)によって構成される。以下にそれらのプログラムとメールの流れを紹介する。

MUA(Mail User Agent)
いわゆるメールクライアントのこと。他にもメーラ、メールリーダなどと呼ばれる。
MTA(Mail Transfer Agent)
メールを別のメールサーバに送信したりMDAに渡したりするもの。
MDA(Mail Delivery Agent)
MTAから受け取ったメールをメールボックスに保存するもの。
MRA(Mail Retrieval Agent)
メールを受信するもの。
MSA(Mail Submission Agent)
MUAとMTAの間で認証などを行うもの。メールの仕組みができたばかりのころはなかったが、現在はセキュリティのためにMSAを間に置くのが主流。

メールクライアント

前述のHTTPのサンプルと同様に、telnetを使ってSMTPとPOP3のサーバにアクセスした例を以下に示す。

SMTP
user% telnet 192.168.1.101 25
Trying 192.168.1.101...
Connected to versus.
Escape character is '^]'.
220 pied-piper.net ESMTP
HELO pied-piper.net
250 pied-piper.net
MAIL FROM: me@pied-piper.net
250 ok
RCPT TO: user@pied-piper.net
250 ok
DATA
354 go ahead
From: me@pied-piper.net
Subject: test

Hello, User
.
250 ok 1397490184 qp 6800
QUIT
221 pied-piper.net
Connection closed by foreign host.
ちなみにSMTPの通信には,DATA以前に入力した情報を使用し,それ以降はメールヘッダのために使用する。 それゆえヘッダ部分は,偽装することも可能であるが,いくつかのSMTPサーバは,そのような怪しいメールの受け取りを拒否する。
POP3
user% telnet 192.168.1.101 110
Trying 192.168.1.101...
Connected to versus.
Escape character is '^]'.
+OK <6798.1397490101@pied-piper.net>
USER user
+OK
PASS hogehoge
+OK
STAT
+OK 125 3714019
LIST
+OK 
1 754
2 1846
3 782
RETR 1
+OK 
Return-Path: <user@pied-piper.net>
Delivered-To: user@pied-piper.net
Received: (qmail 6615 invoked by uid 0); 15 Apr 2014 00:22:33 +0900
Received: from unknown (HELO pied-piper.net) (192.168.1.111)
  by 192.168.1.101 with SMTP; 15 Apr 2014 00:22:33 +0900
From: me@pied-piper.net
Subject: test
Hello, User

.

QUIT
+OK 
Connection closed by foreign host.

SMTP,POP3プログラミング

SMTPやPOP3ライブラリを使用したサンプルコードを以下に示す。

SMTP
#!/usr/bin/python2.7

import smtplib,email.utils
from email.mime.text import MIMEText

FROM = "i@pied-piper.net"
TO = "you@example.pied-piper.net"

msg = MIMEText('This is the body of the message.')
msg['To'] = email.utils.formataddr(('You', TO))
msg['From'] = email.utils.formataddr(('O_Messiaen', FROM))
msg['Subject'] = 'Hello'

server = smtplib.SMTP('192.168.1.101', 25)
server.set_debuglevel(True) # show communication with the server
try:
    server.sendmail(FROM, [TO], msg.as_string())
finally:
    server.quit()
POP3
#!/usr/bin/python2.7

import poplib

pop3 = poplib.POP3("192.168.1.201", 110)
pop3.user("user")
pop3.pass_("hogehoge")
retr = pop3.retr(len(pop3.list()[1]))
"\n".join(retr[1])


セッション層

OSI参照モデル(7階層モデル)では,アプリケーション層とトランスポート層の間に,プレゼンテーション層とセッション層がある。セッション層では,通信の開始時や終了時などに送受信するデータの形式などを規定する。セッション層には例えばSSL(Secure Socket Layer)がある。SSLの詳細は省略するが,それは階層の上位のレイヤに対して暗号化や認証,完全性を提供する。昨今,httpやsmtp,pop3などのアプリケーション層のプロトコルを安全に利用するために,SSLを利用することは珍しくない。

以下にSMTP-SSLの利用例を示す。ここではopensslコマンドを使用する。opensslの機能はさまざまあり,引数としてコマンドを指定する。 以下の例では,s_clientを使用する。telnetやnc(netcat)がTCP(トランスポート層)での通信を提供するソフトウェアと考えるなら,opensslのs_clientコマンドはSSL(セッション層)での通信を提供するソフトウェアと考えれば良い。オプションの詳細については"man s_client"で閲覧できる。

user% openssl s_client -connect smtp.gmail.com:465 -crlf -ign_eof
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=smtp.gmail.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEdjCCA16gAwIBAgIIGcMF7jeVMoAwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
   ー中略ー
    Verify return code: 20 (unable to get local issuer certificate)
---
220 mx.google.com ESMTP n7sm9349346pdl.90 - gsmtp
EHLO localhost
250-mx.google.com at your service, [153.198.XXX.XXX]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
認証方法を入力する。
AUTH LOGIN
334 VXNlcm5hbWU6
AUTH LOGINで認証を行う場合,ユーザ名とパスワードをそれぞれbase64でエンコードしたものを使用する。ここでXXXXXXXXXXはユーザ名をエンコードしたもの,YYYYYYYYYYはパスワードをエンコードしたものである。
XXXXXXXXXX
334 UGFzc3dvcmQ6
YYYYYYYYYY
235 2.7.0 Accepted
エンコードは,次のようにbase64コマンドやopensslのencコマンドで行うことができる。また,opensslのencコマンドのマニュアルはs_clientと同様"man enc"で閲覧できる。
  • user% echo "me@gmail.com" | base64 
    bWVAZ21haWwuY29tCg=
  • user% echo "me@gmail.com" | openssl enc -e -base64
    bWVAZ21haWwuY29tCg=
パスワードのエンコードも同様である。XXXXXXXXXXやYYYYYYYYYYの部分にはこの結果を貼り付ければ良い。 これ以降は通常のSMTPと同じように行えば良いが,ここではあえてHTMLメールを送信する例を紹介する。
MAIL From: <me@gmail.com>
250 2.1.0 OK n7sm9349346pdl.90 - gsmtp
RCPT To: <you@gmail.com>
250 2.1.5 OK n7sm9349346pdl.90 - gsmtp
DATA
354  Go ahead n7sm9349346pdl.90 - gsmtp
Subject: html-mail
Mime-Version: 1.0;
Content-Type: text/html; charset="ISO-8859-1";
Content-Transfer-Encoding: 7bit;

<!DOCTYPE HTML>
<html lang="ja-JP">
<body>
<h1>こんにちわ</h1>
</body>
<html>
.
250 2.0.0 OK 1413388691 n7sm9349346pdl.90 - gsmtp
QUIT
221 2.0.0 closing connection n7sm9349346pdl.90 - gsmtp
read:errno=0

一覧