반응형
작성일: 2026년 1월 20일

 

내가 접속하려는 SSH 서버(Host-A)가 방화벽 내부에 있거나 NAT 장치로 보호되고 있는 내부 네트워크(즉, Private network)에 존재하는 경우에 Host-A로 바로 접속이 안 될 수 있다.

그럴 때는 일단 접속이 되는 SSH 서버로 로그인하고, 그 이후에 최종적으로 Host-A로 SSH 로그인하게 된다.

예를 들면,

[ 내 PC ] -> [ Host-B ] -> [ Host-A ] 

순서로 접속한다고 가정하면,

 

1)  내 PC에서 Host-B로 SSH 로그인

2)  Host-B에서 Host-A로 SSH 로그인

 

이렇게 하면, SSH 접속 명령을 2번 수행해야 하는 불편함이 생기는데, 

이런 불편함을 줄일 수 있는 SSH CLI 명령의 '-J' 옵션을 사용하는 것이 권장된다.

 

위와 같은 상황에서 한번에 SSH 명령으로 접속한다면,

$ ssh -i ~/.ssh/my_key -J gildong@HostB  bts@HostA

 

참고로, "~/.ssh/my_key"는  HostB 접속용 Private Key이다.

 

여기서 "HostB"를 Jump Host라고 부른다.

 

만약, 위와 같이 '-J' 옵션을 사용했을 때 아래처럼 오류 메시지가 나오면 ~/.ssh/config 파일을 작성해야 사용해야 한다.

gildong@211.6.8.9: Permission denied (publickey).
Connection closed by UNKNOWN port 65535

 

 

$ cat ~/.ssh/config

Host my-new-jump-host
    HostName 211.6.8.9
    User gildong
    IdentityFile ~/.ssh/my-private-key-for-jump.pem

Host 192.168.122.10
    User bts
    ProxyJump my-new-jump-host
    IdentityFile ~/.ssh/my-private-key-for-end-node.pem
    
$ chmod 600 ~/.ssh/config

 

아래와 같이 SSH 접속해본다.

$ ssh 192.168.122.10

 

주의: 위 명령을 수행할 때, account name을 사용하지 않도록 한다. '192.168.122.10'에 대한 설정 내용에 이미 bts라는 user 정보다 있기 때문.
반응형
작성일: 2026년 1월 5일

 

SDN Controller 중에서 그나마 최근까지 개발을 꾸준하게 유지하고 있는 ODL(OpenDaylight).

막상 ODL을 설치하려고 보면, ODL Version과 Java Version의 궁합이 맞지 않아서 설치가 쉽지 않다.

 

나도 몇번 ODL version 및 Java Version을 바꾸어 가면서 설치 & 실패를 반복하면서 찾아낸 조합이 아래와 같다.

 

  • ODL Version: Scandium(0.21.3) 2024년에 릴리즈
  • Java Version: Java 21 (패키지 이름은 openjdk-21-jdk)

설치 절차는 간단하다.

 

Java 설치하기

$ sudo apt install openjdk-21-jdk

$ java -version  
openjdk version "21.0.9" 2025-10-21

 

 

ODL(OpenDaylight) 설치하기

$ wget https://nexus.opendaylight.org/content/repositories/opendaylight.release/org/opendaylight/integration/karaf/0.21.3/karaf-0.21.3.tar.gz

$ tar xf karaf-0.21.3.tar.gz

$ ./bin/karaf

Karaf started in 0s. Bundle stats: 20 active, 20 total
                                                                                           
    ________                       ________                .__  .__       .__     __       
    \_____  \ ______   ____   ____ \______ \ _____  ___.__.|  | |__| ____ |  |___/  |_     
     /   |   \\____ \_/ __ \ /    \ |    |  \\__  \<   |  ||  | |  |/ ___\|  |  \   __\    
    /    |    \  |_> >  ___/|   |  \|    `   \/ __ \\___  ||  |_|  / /_/  >   Y  \  |      
    \_______  /   __/ \___  >___|  /_______  (____  / ____||____/__\___  /|___|  /__|      
            \/|__|        \/     \/        \/     \/\/            /_____/      \/          
                                                                                           

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown OpenDaylight.

opendaylight-user@root>

 

OLD(OpenDaylight) 전체 버전 리스트를 보고 싶다면, 아래 Wiki page의 "Release" 섹션을 참고.

https://en.wikipedia.org/wiki/OpenDaylight_Project

 

 

OVS(Open vSwitch)와 ODL Controller를 연동

OVS가 설치된 Host 장비에서 아래와 같이 명령을 실행한다.

## 명령 사용 방법
##  ovs-vsctl set-controller "Bridge name" tcp:ODL_CONTROLLER_IP_ADDR:PORT_NUMBER

$ sudo ovs-vsctl set-controller my-br-1 tcp:10.1.4.51:6653
## 또는 TCP port 6633을 사용해도 된다.
$ sudo ovs-vsctl set-controller my-br-1 tcp:10.1.4.51:6633

 

 

반응형
작성일: 2025년 11월 26일

 

OVS Export는 Host 장비(Baremetal 장비)에 설치하고,,

Prometheus, Grafana는 "docker compose"를 이용해서 설치할 때 아래의 문서를 참고할 것!

 

 

Open Virtual Switch(OVS) Exporter 설치하기

설치 설명 문서:

https://github.com/greenpau/ovs_exporter

위 문서를 읽을 때, 주의할 점이 있다.

설치 절차 중에서 설명이 빠져있는 부분이 있는데, `make dist`를 수행해야  위 문서에서 설명하는 `install.sh` 스크립트가 생성된다. `install.sh` 스크립트 생성에 대한 설명이 없어서, 나는 설치 중에 우왕좌왕했었다.

 

Prometheus, Grafana 설치하기 (docker compose를 이용하여 설치)

설치 설명 문서:

https://www.devkuma.com/docs/prometheus/docker-compose-install/

위 문서에서 "script_configs" 설정 부분만 OVS Exporter에 맞게 수정하면 잘 동작한다.

그리고 scrape_interval을 10s 보다 작게 설정하면, container 생성에서 실패하므로 위 문서의 예시에 있는 10s 값을 변경하지 않고 써야 한다.

 

Prometheus 동작 확인하기

OVS exporter, Prometheus, Grafana 설치가 완료되었으면,

Prometheus web console 화면에서

[ Status ] -> [Target health ] 메뉴를 선택하여 "script_configs" 설정 항목에 설정한 exporter와 연동이 잘 되는지 확인한다.

 

Grafana 동작 확인하기

Grafana web console 화면에서

[ Connections ] -> [ Data sources ] 메뉴를 선택하여 Prometheus의 API 연동 주소를 등록한다.

일반적으로 [Connection] 항목의 [Prometheus server URL] 항목에 "http://10.1.1.3:9090" 이렇게 입력하면 되고,

그 외의 항목은 기본값으로 설정한다.

 

Grafana Web Console 화면에서 Prometheus 연동 설정하기

 

 

그리고 나머지는 [ Explore ] 메뉴 또는 [ Dashboards ] 메뉴에서 Prometheus Query를 입력하고 Chart 구성을 하면 된다.

'Network > VirtualSwitch' 카테고리의 다른 글

Open vSwitch(OVS) + ONOS 조합으로 VLAN 패킷 제어  (0) 2023.03.20
반응형
작성일: 2025년 2월 4일

 

 

 

아래 블로그가 Proxy ARP를 쉽게 설명하고 있다. (예제를 이용하여 설명)

 

https://blog.naver.com/eqelizer/20133718343

 

위 블로그가 다루는 내용:

  • Proxy ARP 장점
  • Proxy ARP 단점
  • Proxy ARP 동작 원리 (예제 네트워크 구성도를 이용하여 동작 원리를 설명함)

 

반응형
작성일: 2024년 11월 17일

 

내가 eBPF, XDP의 네트워크 패킷 처리 성능을 측정하다가 목표한 성능 값보다 낮게 나와서 다른 사람들은 얼마나 성능이 나오는지 궁금해서 찾아본 자료이다.

다른 사람들이 테스트한 eBPF 성능 측정 값을 보면, 꽤 좋은 수치가 나온다.

내가 너무 구형 장비에서 테스트한 것이 성능 저하의 원인인 듯하다.

(아래 cilium이 구성한 HW 장비보다 7년 정도 더 오래된 CPU를 사용했음 ㅠㅠ)

 

 

https://cilium.io/blog/2021/05/11/cni-benchmark/

 

CNI Benchmark: Understanding Cilium Network Performance

As more crucial workloads are being migrated to Kubernetes, network performance benchmarks are becoming an important selection criter...

cilium.io

 

네트워크 처리 성능을 끌어올리기 위해 eBPF, XDP를 사용하는 것에 대해 의심할 필요는 없어 보인다.

 


 

반응형

 

작성일: 2024년 7월 16일

 

 

아래 글은 나의 주관적 생각이 포함된 것이므로 정확한 기술 Spec을 원하는 분은 이 글을 참고용으로만 읽고,
이 블로그의 중간에 링크를 달아둔 Official document를 열람하는 것을 권장함.

 

 

XDP 개요  (들어가는 글)

XDP(eXpress Data Path)는 OS network stack을 우회하여 별도의 user application으로 보내고 받도록 하는데 사용되는 eBPF 기반의 data path이다.

Linux kernel version 4.8부터 XDP를 포함하므로 XDP 프로그래밍을 위해서 별도로 library를 설치할 필요는 없다.

 

아래 그림만 잘 들여다보면, XDP_* 처리(Action)에 대한 감이 온다.

 

XDP를 이용한 Network Packet Flow를 제거하기

 

위 그림에서 (start), interface output을 물리 네트워크 포트 또는 NIC port 라고 가정하고 보면 Packet 흐름이 자연스러워진다.

그리고, 이 블로그에서는 (start), interface output 가 동일 NIC port라고 가정하고 나머지 내용을 설명할 것이다.   

 

XDP_*  Action Code Description
XDP_PASS 원래의 network packet이 처리되는 것처럼 Network stack으로 보낸다.
(즉, XDP가 없더라도 원래 동작하던 network packet 처리)
XDP_DROP 패킷을 drop (폐기)
XDP_ABORTED Trace point exception과 함께 해당 packet을 drop (폐기)
XDP_TX 위 그림에 묘사된 것처럼 아무 처리하지 않고, 바로 NIC port로 되돌려 보낸다. (반송 처리)
XDP_REDIRECT AF_XDP Address Family를 통해 packet을 다른 NIC port로 보내거나 
User Space Socket으로 redirect한다.
---
  참고로 AF_XDP address family는 Linux kernel 4.18부터 추가되었다.

 

 

예제 / 실습 자료

위 내용을 바탕으로 실습하고자 한다면, 아래 tutorial을 참고할 것!

 

  XDP tutorial : 문서 링크 열기

        아래 git repo에 여러 실습 예제가 있는데, 그 중에서 "basic01-xdp-pass"와 같은 쉬운 예제부터 실습하면서

        전체 처리 절차를 이해하는 추천함!

 

  Tutorial one liners (bpftrace) : 문서 링크 열기

 

  Go Packet Generator (go-pktgen) : 문서 링크 열기

    -> 위 go-pktgen 프로그램은 아래 go package를 사용하므로, 아래 golang pkg source code 분석하는 것을 추천.

          XDP Go Package : 소스 코드 링크 열기   

 

 

Linux kernel source code에서 XDP 관련 코드를 찾아보기 (예시)

Linux kernel source code에서 network driver와 관련한 code를 찾아 보면, 

XDP_*와 관련있는 부분을 쉽게 만날 수 있다.

그 중에서 몇 개를 여기에 적어보겠다.

 

##
## File: linux/latest/source/drivers/net/ethernet/intel/i40e/i40e_txrx.c
##

... 중간 생략 ...
/**
 * i40e_run_xdp - run an XDP program
 * @rx_ring: Rx ring being processed
 * @xdp: XDP buffer containing the frame
 * @xdp_prog: XDP program to run
 **/
static int i40e_run_xdp(struct i40e_ring *rx_ring, struct xdp_buff *xdp, struct bpf_prog *xdp_prog)
{
	int err, result = I40E_XDP_PASS;
	struct i40e_ring *xdp_ring;
	u32 act;

	if (!xdp_prog)
		goto xdp_out;

	prefetchw(xdp->data_hard_start); /* xdp_frame write */

	act = bpf_prog_run_xdp(xdp_prog, xdp);
    
	switch (act) {
    
	case XDP_PASS:   ## NOTE: 따로 처리할 것이 없다.
		break;       ##       그냥, 원래 하던대로 network stack으로 보내면 된다.
        
	case XDP_TX:     ## NOTE: RX 패킷이 들어온 NIC을 찾아서 TX 패킷을 그 NIC으로 보내도록 한다.
		xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index];
		result = i40e_xmit_xdp_tx_ring(xdp, xdp_ring);
		if (result == I40E_XDP_CONSUMED)
			goto out_failure;
		break;
        
	case XDP_REDIRECT:
		err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
		if (err)
			goto out_failure;
		result = I40E_XDP_REDIR;
		break;
        
	default:
		bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act);
		fallthrough;
        
	case XDP_ABORTED:  ## NOTE: 패킷을 폐기
out_failure:
		trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
		fallthrough; /* handle aborts by dropping packet */
        
	case XDP_DROP:     ## NOTE: 패킷을 폐기
		result = I40E_XDP_CONSUMED;
		break;
	}
    
xdp_out:
	return result;
}
... 중간 생략 ...

 

 

 

 


 

eBPF 공식 문서

What is eBPF?

  문서 링크: https://ebpf.io/what-is-ebpf/

 

The eBPF Library for Go

  문서 링크: https://ebpf-go.dev/

 

 

 


추천 글

eBPF/XDP: 당신만 모르는 안전하고 빠른 Networking

https://pangyoalto.com/ebpf-and-xdp/

 

eBPF/XDP: 당신만 모르는 안전하고 빠른 Networking

[요약] * eBPF: kernel space 내에서 프로그램을 실행할 수 있도록 하여 어플리케이션 개발자가 런타임에 OS의 기능을 사용할 수 있도록 하는 기술 * XDP: eBPF를 기반으로 한 기술로 packet processing을 할 수

pangyoalto.com

 

 

Unlocking Network Performance with XDP and eBPF

https://medium.com/@khushichhillar02/unlocking-network-performance-with-xdp-and-ebpf-67c712128025

 

Unlocking Network Performance with XDP and eBPF

XDP, eXpress Data Path, is a high-performance networking technology in the Linux kernel that allows for fast and efficient packet…

medium.com

 

Kernel-bypass techniques for high-speed network packet processing(XDP, DPDK, eBPF, SmartNIC)

https://youtu.be/MpjlWt7fvrw?si=bnUQJmA0O3qRf3Jg

 

 

 

WireGuard로 VPN 서버 구축하기

아래 문서에서 다루는 내용은;

  • WireGuard
  • KeyCloak SSO 연동
  • Kernel networking stack을 이용하여 특정 Group 접근을 제어 
  • VPN server에서 사용하는 인증(Authentication)
  • eBPF를 이용한 패킷 필터링(Packet filtering)
  • eBPF map (Key/Value store)

https://tech.devsisters.com/posts/wireguard-vpn-2/

 

 


 

반응형

 

작성일: 2024년 6월 4일

 

Network Traffic을 다루는 앱을 개발하다보면, TLS 또는 HTTPS로 암호화한 통신 내용을 봐야 할 때가 있다.

원칙적으로는 TLS 통신에서 제3자가 패킷 내용을 열람하는 것이 불가능하지만,

내 PC에 저장된 Master Secret 값을 이용하면 복호화가 가능하다. (내 PC는 제3자가 아니니까 이런 복호화가 가능한 얘기가 된다)

 

참고: 3가지 복호화 방법

Master Secret 값을 이용하는 경우 외에도 TLS Payload를 복호화(Decryption)하는 방법이 있다.

Wireshark 매뉴얼에 보면, Master Secret을 포함하여 총 3가지 방법을 소개하고 있다.

방법 A : (Pre)-Master Secret 정보가 담겨있는 Key load file을 사용하여 복호화하기

이 방법이 범용적으로 사용되는 복호화 방법.

Diffie-Hellman(DH) Key 교환이 발생하더라도 (Pre)-Master Secret 정보를 이용하면 복호화가 된다.

이 블로그의 대부분 내용이 이 방식으로 복호화하는 방법이 설명되어 있다.

 
방법 B : RSA private key (예:  PEM 포맷의 private key 파일)을 이용하여 복호화하기

TLS 연동할 Peer 노드(예: 서버)의 RSA private key를 한번만 Wireshark에 등록하면 되므로 가장 편하게 설정할 수 있다.

단, 아래와 같이 조건을 모두 만족하는 경우에만 RSA private key를 사용하여 복호화하는 것이 가능하다.

  • 조건1: Cipher suite가 (EC)DHE 계열이 아니어야 한다.
  • 조건2: TLS 1.0 ~ 1.2만 허용됨. TLS 1.3에서는 복호화할 수 없음.
  • 조건3: Wireshark에 등록할 Private key는 반드시 Server certificate이어야 한다. client certificate 또는 CA(Certificate Authority) certificate은 안 된다.
  • 조건4: TLS handshake 절차에서 'ClientKeyExchange' 과정이 포함되어야 함
즉, 위 4가지 조건을 모두 만족해야 햐는데 현실적으로 요즘 TLS 통신 환경에서 RSA private key를 이용하여 복호화하는 것이 거의 어렵다는 뜻 ㅠㅠ

 

방법 C : Pre-Shared-Key(PSK) 정보를 이용하여 복호화하기

수준 높은 보안을 요구하는 곳에서 PSK를 사용하지 않고,
PSK를 사용하는 것이 흔한 경우가 아니니까, 설명을 생략~

 

 

 

그렇다면,  Master Secret이라는게 무엇이길래 패킷 복호화가 가능한 것일까?

만약 Server / Client 간 통신이 mTLS 방식으로 연결된다면, 아래와 같이 절차를 따를 것이다.

  1. Client는 Server certificate을 받아서 믿을만한 Network peer인지 확인 (즉, Root CA가 서명한 Certificate인지 확인)
  2. Server는 Client certificate을 받아서 믿을만한 Network peer인지 확인
  3. 서로 믿을만하다고 판단되면, 대칭키 교환 (여기서 교환한 대칭키는 Server, Client가 패킷을 암호화 및 복호화 할 때 사용)
  4. Server, Client가 서로 암호화한 패킷을 주고, 받을 쪽에서는 패킷을 받으면 복호화 처리 (이 때 대칭키를 사용함)

위 mTLS 핸드쉐이킹 절차 3번에서 교화한 대칭키만 있으면, Server / Client 간에 주고 받은 암호화된 HTTPS(또는 TLS) 패킷을 복호화할 수 있다.

 

이론적으로는 위와 같고, 실제로 Chrome browser 또는 Firefox browser로 HTTPS 패킷을 보내고 받은 내용을 복호화하려면 아래와 같이 해야 한다.

 

 

##
## Firefox 브라우저로 테스트할 때.
## 
$ export SSLKEYLOGFILE=/tmp/sslkey.log
$ open /Applications/Firefox.app

##
## Chrome 브라우저로 테스트할 때.
##
$ export SSLKEYLOGFILE=/tmp/sslkey.log 
$ open /Applications/Google\ Chrome.app

 

 

Wireshark을 macOS에서 실행한 경우, 아래의 순서로 설정 화면을 열어 본다.

 

[ Wireshark ]  ->  [ Preferences ]  ->  [ Protocols ]  ->  [ TLS ]  ->  [ (Pre)-Master-Secret log filename ]

 

위 순서로 설정 화면을 오픈하고, 아래 예시 화면처럼 Master-Secret log 파일 경로를 입력하면 된다.

 

 

 

[ OK ] 버튼을 클릭하고, Firefox 브라우저에서 웹 브라우징을 해보면

TLS의 Payload가 눈으로 볼 수 있는 HTTP Payload로 복호화된 것을 확인할 수 있다. 

 

 


참고: 위와 동일한 내용이지만 원문을 읽고 싶다면, 아래 문서 링크를 클릭할 것 !

 

https://wiki.wireshark.org/TLS#using-the-pre-master-secret

 

TLS - Wireshark Wiki

Some applications (such as email) use a single port for both unencrypted and encrypted sessions. To change from unencrypted to encrypted, (START)TLS is used. When a single port directly uses the TLS protocol, it is often referred to as SSL.

wiki.wireshark.org

 

 

 


 

반응형

 

2024년 4월 2일

 

 

일단, 메모만 해놓고 나중에 자세히 스터디하기~

 

 

https://www.ntop.org/products/packet-capture/pf_ring/

 

PF_RING

 

 

 

 

PF_RING Modules

 

 

 

 

https://www.ntop.org/products/packet-capture/pf_ring/pf_ring-zc-zero-copy/

 

 

 

Zero Copy Operations to KVM VM instances

 

 

 

 

 

 


 

 

+ Recent posts