VPN接続入門

### VPN概要
– 内部ネットワークあどれすは通常インターネットからDNSの名前解決ができない
– 接続先がプライベートアドレスを使っている場合もインターネットを介して接続できない
– 誰でも内部ネットワークに通信できるとセキュリティ上問題
— VPNだと認証後に接続先ネットワークと直接接続されているように使うことができる
— VPNはファイヤーウォールと一緒、個別に構築する場合はDMZに配置する
– 専用線は第三者がアクセスできないので通信の盗聴を予防できる
– VPNであれば既存の公衆回線を利用できる
– 離れた場所にあるネットワークに対し、同じLANにいるようなアクセスが実現できる

### トンネリング
元々のパケットにインターネットで使われるIPアドレスを追加することでインターネットでルーティングできるようになる。受信側では、追加されたIPアドレスを外して送信先のIPアドレスと通信
パケットにアドレス等を追加することをカプセル化と言う
データの暗号化には共通鍵暗号方式がよく使われる(DES, 3DES, RC4, AES, RSAなど)

### VPN接続の認証や共通鍵作成
ID, Passwordハッシュが使われる。MD5, SHA1, SHA2等が使われる
データ等をハッシュを利用してMAC値を生成(HMACと言う)

閉域網はインターネットとは分離隔離された形で閉域網を構築している

なるほどー、閉域網かあ

AWS Direct connectとは?

AWSが提供する専用接続サービスで、ユーザのネットワーク環境からAWSまでインターネットを経由せずプライベートな接続を確立することができる。
ユーザがAWSのパートナー設備に用意された相互接続ポイント(AWS Direct Connectロケーション)と間接的に接続する
「安定性」「セキュリティ」「コスト」

HULFTとは?

HULFTとは、ファイルという形になった情報を転送し、その情報を転送する際に発生する前後の処理を統合的に扱うためのソフトウェア

→ TPC SYN (TCP接続を確立する際にクライアントから送られるパケット)
← TCP SYN+ACK(接続を受け入れる際にはACKフラグが一緒になったSYN/ACKパケットで応答する。TCPの3way handshake)
→ TPC ACK
→ 配信情報を送信
← 応答
→ ファイルデータ送信(小分けにしてデータを送信)
← 受信済みデータ量返信
→ TPC FIN
← TCP FIN+ACK
→ TPC ACK
TCP接続確立後、配信側で必要に応じてコード変換、圧縮、暗号化などの前処理が行われる
配信側は前処理が終わったファイルをTCP接続で集信側に送信
集信側は、暗号化されたデータの複合、圧縮されたデータの解凍、コード変換などの処理を必要に応じて行う
ファイル転送終了後、TCP接続が切断され、HULFT配信が終了する

ファイル転送前処理: ファイル入力、コード返還(各種汎用機で使われている文字コードに対応)、圧縮(ランレングス法に似た圧縮とDeflate圧縮の2種類)、暗号化(HULFT暗号、C4S暗号、AES)、転送の順番で配信が行われる
※メモリ上で行われるため、前後処理のための中間ファイル等は生成されない

hulftのistall
# pwd
/usr/local/HULFT/insttmp
# ./installer
インストールの開始
シリアル番号とプロダクトキーの入力
利用期間ライセンスキー
インストール方法の選択
トレースログ出力方式の選択
インストール条件の確認
インストールの終了
環境変数の設定
実行モジュール格納ディレクトリの設定
L HULFTの実行モジュールがある、実行モジュール格納ディレクトリをシェルの環境変数に設定します。環境変数名は、「HULEXEP」です。この環境変数を設定することにより、HULFTが実行するプログラムのPATHを自動的に検索できます。また、このディレクトリをPATHに設定することにより、HULFTの実行モジュールがあるディレクトリ以外からもHULFTを起動できます。
# HULEXEP=/usr/local/HULFT/bin
# export HULEXEP
# PATH=/usr/local/HULFT/bin:$PATH
# export PATH

環境設定ファイル格納ディレクトリの設定
L HULFTが使用する環境設定ファイルのある、環境設定ファイル格納ディレクトリをシェルの環境変数に設定します

環境変数の確認
# echo $HULPATH
/usr/local/HULFT/etc
# echo $HULEXEP
/usr/local/HULFT/bin

# echo $PATH (sh系の場合)
/usr/local/HULFT/bin:/usr/local/bin:/bin:/usr/bin:/usr/sbin ..

配信処理を行うためには、配信デーモンを起動する必要があります。
# hulsndd
集信デーモンの起動
L 集信処理を行うためには、集信デーモンを起動する必要があります。
# hulrcvd
要求受付デーモンの起動
L 相手からの要求を受け付けるためには、要求受付デーモンを起動する必要があります。
HULFTの起動確認
L 各デーモン起動コマンド入力後、以下のコマンドなどによりプロセスの状態を確認します。
# hulsndd
# hulrcvd
# hulobsd
# ps -ef | grep hul
root 21207 1 0 22:49:30 ? 0:00 hulrcvd
root 21205 1 0 22:49:26 ? 0:00 hulsndd
root 21209 1 0 22:49:32 ? 0:00 hulobsd

管理情報の登録
L HULFTでは配信側と集信側に同一のファイルIDを指定します。ファイルIDは50文字以内の英数字で指定します。ファイルIDに関連付けられた管理情報を元にファイル転送を行います。ファイルIDは1ファイルごとに配信側(配信管理情報)および集信側(集信管理情報)に登録する必要があります。
配信要求(配信側起動のファイル転送)
L 配信要求は転送するファイルを持つ側からの起動でファイル転送を行う場合に使用します。
履歴の確認(配信側起動のファイル転送)
送信要求(集信側起動のファイル転送)
要求状態の確認(集信側起動のファイル転送)
L「送信要求(集信側起動のファイル転送)」で行ったファイル転送の結果を確認します。配信側ホストには配信履歴が表示され、集信側ホストには集信履歴が表示されます。

FTP接続の場合はファイルの整合性チェックまで行わない

HULFTが何やってるかは大体わかった。

[CentOS8]ビルトインサーバにアクセス出来ない時

vagrant & CentOS8でビルトインサーバを起動します。

$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) …

なんでやねん。

Vagrantifle

  config.vm.network "private_network", ip: "192.168.34.10"

プロキシの設定等はしていない。どうやらfirewallが怪しい、ということで
$ sudo firewall-cmd –list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0 eth1
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

あ、やっぱり。http, 8000がアクセス出来ません。

$ sudo firewall-cmd –add-service=http –zone=public –permanent
$ sudo firewall-cmd –add-port=8000/tcp –zone=public –permanent
$ firewall-cmd –reload

出来ました。アホみたいなミスでした。
CentOS8だとデフォルトでfirewallがonになってるんですね。そういえば、sakuraのvpsなどもポートフィルタリングがデフォルトでonになってます。クワバラクワバラ

[PHPQuery]プロキシ経由でスクレイピングする

無料プロキシリストからproxyを取得してスクレピングする。
http://www.freeproxylists.net/ja/?c=JP&pt=&pr=&a%5B%5D=0&a%5B%5D=1&a%5B%5D=2&u=0

$url = "https://www.google.com/";
// $proxy_url = "153.126.160.91:80";
$proxy_url = "133.167.65.45:8080";

$context = stream_context_create(array(
      'http' => array(
         'method' => 'GET',
         'header'=>'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/00100101 Firefox/13.0.1\r\nReferer: https://www.google.com/webhp?gl=us&hl=en&gws_rd=cr&pws=0',
         'ignore_errors'=>true,
         'proxy' => $proxy_url,
      )
   ));
$html = file_get_contents($url, FALSE, $context);
$doc = phpQuery::newDocument(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));


echo $doc["title"]->text();

$ php test.php
Google

設定するプロキシによっては、接続を拒否される場合があるので、テストして確認が必要
Cannot connect to HTTPS server through proxy in /home/vagrant/test/test.php on line 17

なるほどー凄い理解した^^

vagrantでプロキシサーバを使用したい

VagrantのゲストOSにProxy設定を行うには、vagrant-proxyconfを使う。plug-inのインストールが必要

$ vagrant plugin install vagrant-proxyconf
$ vagrant plugin list
vagrant-proxyconf (2.0.10, global)
vagrant-vbguest (0.20.0, global)

### focalfossa
vagrantのubuntu/focal64を使いたいと思う
$ vagrant init ubuntu/focal64

公開プロキシのサイトを検索します

とりあえず、最初なので日本のプロキシサーバを使う
http
43.248.24.158 51166
https
133.167.65.45 8080

Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/focal64"
  config.vm.network "private_network", ip: "192.168.33.10"

  if Vagrant.has_plugin?("vagrant-vbguest")
      config.vbguest.auto_update = false  
  end

  if Vagrant.has_plugin?("vagrant-proxyconf")
    config.proxy.http = "http://43.248.24.158:51166/"
    config.proxy.https = "http://133.167.65.45:8080/"
    config.proxy.no_proxy = "localhost,127.0.0.1,192.168.33.10"
  end
end

$ vagrant up

$ printenv http_proxy https_proxy
http://43.248.24.158:51166/
http://133.167.65.45:8080/

なるほど、proxyについて完全に理解した🔥

プロキシサーバーとは

プロキシサーバとは、内部ネットワークとインターネットの境界で動作し、両者間のアクセスを代理するもの
キャッシュ機能がある
– キャッシュ、ユーザー認証、フィルタリング、ウィルス対策、匿名性確保

### プロキシサーバのメリット
– プロキシ上にログが残る
– プロキシサーバを経由すると、端末のIPが相手に残らない

### 注意点
– 公開プロキシは個人情報を抜き取るものもあるため、個人情報を扱う場合は、公開プロキシは使用しない

リバースプロキシとは、外部インターネットからサーバーへアクセスされる通信を中継する仕組み

なるほど、仕組みは理解したが、使ってみないとわからんな。

[kernel]ネットワーク(TCP/IP)

IP:16.42.0.9

ネットワークアドレス:16.42
ホストアドレス:0.9

サブネットアドレス:16.42.0
ホストアドレス:9

IPアドレスはネットワーク管理者によって割り当てられる
16.42.0と16.42.1というようにサブネットを変える

IPアドレスはIPパケットに含まれている
送信元、送信先のIPはIPヘッダに含まれる
同一のIPサブネットのホスト間では直接IPパケットを送信できるが、それ以外はゲートウェイに送信

TCPはパケットの送受信のためにIPを使用する
IPアドレスだけでなく、アプリケーションのポート番号も指定しなければならない

### linuxのnetwork
Network Application: user
Socket Interface: BSD Socket, INET Sockets
Protocol Layer: TCP, UDP IP
Network Devices: PPP, SLIP, Ethernet

TCPパケットは番号付けされているので、送信されたデータが正しく受信されたか確認する

### BSD Socket Interface
UNIX, INET, AX25(アマチュア無線)、IPX、APPLETALK, X25
Soket type: Stream, Datagram, Raw, Reliable Delivered Messages, Sequenced Packets, Packet

### INET Sockets
インターネットアドレスファミリーをサポート
システムコールで新規ソケットを作成する際は、アドレスファミリ、ソケットタイプ、プロトコルに関する識別子を渡す

INET BSD ソケット上でコネクションを確立
ふたつのアプリケーション間で仮想サーキットを構築する
TCP セグメントには、コネクション情報、開始セグメントのシーケンス番号(sequence number)、接続を開始したホスト側が処理できるセグメントの最大サイズ(maximum segment size, MSS)、送信および受信の際のウィンドウサイズ(window size)、等が含まれる

待機(listen)状態のソケット上のaccept操作ルーチンは、その socket データ構造体から、新規のsocketデータ 構造体を複製

### IP層
socket buffer:ソケットバッファもしくは sk_buff を使用してプロトコル間やネットワークデバイスとの間でデータを受け渡し
head, data, tail, end
sk_buff: push, pull, put, trim

[C言語]ICMP

ICMPとはInternet Control Message Protocol
Internet Protocolのデータグラム処理における誤りの通知や通信に関する情報の通知などのために使用される

#include <stdio.h>

#include <sys/socket.h> // Internet Protocol family
#include <netinet/in.h> // Internet Protocol family

#include <netinet/ip.h>  // IPヘッダ構造体
#include <netinet/ip_icmp.h> // ICMPヘッダ

unsigned short checksum(unsigned short *buf, int bufsz){

	unsigned long sum = 0;

	while(bufsz > 1){
		sum += *buf;
		buf++;
		bufsz -= 2;
	}

	if(bufsz == 1){
		sum += *(unsigned char *)buf;
	}

	sum = (sum & 0xffff) + (sum >> 16);
	sum = (sum & 0xffff) + (sum >> 16);

	return ~sum;
}

int main(int argc, char** argv[]){

	int sock;
	struct icmphdr hdr;
	struct sockaddr_in addr;
	int n;

	char buf[2000];
	struct icmphdr *icmphdrptr;
	struct iphdr *iphdrptr;

	if(argc != 2){
		printf("usage : %s IPADDR\n", argv[0]);
		return 1;
	}

	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(argv[1]);

	sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	if(sock < 0){
		perror("socket");
		return 1;
	}

	memset(&hdr, 0, sizeof(hdr));

	hdr.type = ICMP_ECHO;
	hdr.code = 0;
	hdr.checksum = 0;
	hdr.un.echo.id = 0;
	hdr.un.echo.sequence = 0;

	hdr.checksum = chechsum((unsigned short *)&hdr, sizeof(hdr));

	n = sendto(sock, (char *)&hdr, sizeof(hdr), 0, (struct sockaddr *)&addr, sizeof(addr));
	if (n < 1){
		perror("sendto");
	}

	memset(buf, 0, sizeof(buf));

	n = recv(sock, buf, sizeof(buf), 0);
	if(n < 1){
		perror("recv");
	}

	iphdrptr = (struct iphdr *) buf;

	icmphdrptr = (struct icmphdr *)(buf + (iphdrptr->ihl * 4));

	if(icmphdrptr->type == ICMP_ECHOREPLY){
		printf("received ICMP ECHO REPLY\n");
	} else {
		printf("received ICMP %d\n", icmphdrptr->type);
	}

	close(sock);
	

	return 0;

}

[C言語]UDP

UDPはデータが宛先に届いたかどうかを関知しない為、到着を保証しない
複数の相手に同時にデータを送信できる、TCPは1対1のユニキャストのみ
TCPよりリアルタイム性が高い
用途は映像、音楽のストリーミング、Voice Over IPなど

### UDP受信
– ソケットを作る
– bindするIPアドレスとポートを設定
– ソケットに名前をつける
– データを受け取る

#include <stdio.h>
#include <sys/types.h> // typedef シンボルおよび構造体のコレクション
#include <sys/socket.h> // Internet Protocol family
#include <netinet/in.h> // Internet Protocol family

int main(int argc, char** argv){

	int sock;
	struct sockaddr_in addr; // sockaddr_inはIPアドレスやポート番号を保持する為の構造体

	char buf[2048];

	sock = socket(AF_INET, SOCK_DGRAM, 0); // ソケットの作成

	addr.sin_family = AF_INET; // アドレスファミリ
	addr.sin_port = htons(12345); // ポート番号、 htonsはネットワークバイトオーダに変換
	addr.sin_addr.s_addr = INADDR_ANY; // IPアドレス

	bind(sock, (struct sockaddr *)&addr, sizeof(addr)); // sockはソケットとアドレスの結合

	memset(buf, 0, sizeof(buf)); // バイトメモリブロックのセット
	recv(sock, buf, sizeof(buf), 0); // ソケットからメッセージを受け取る

	printf("%s\n", buf);

	close(sock);

	return 0;

}

### UDP送信
– ソケットを作る
– 宛先を指定して送信

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(){
	
	int sock;
	struct sockaddr_in addr;

	sock = socket(AF_INET, SOCK_DGRAM, 0);

	addr.sin_family = AF_INET;
	addr.sin_port = htons(12345);
	addr.sin_addr.s_addr = inet_addr("127.0.0.1");

	sendto(sock, "HELLO", 5, 0, (struct sockaddr *)&addr, sizeof(addr));

	close(sock);

	return 0;
}

TCP/IPはデータを切れ目のないストリームとして扱う、ストリームのイメージは固定された通信路
一方、UDPはデータグラム(塊)として扱う

TCPとUDPについてわかってきました。