Linux
- Linux에서 즐길만한 Game 프로그램 모음 2023.08.24
- Linux Kernel Source 분석 자료 및 동영상 강의 모음 2023.08.09
- Linux Kernel / RCU (Read-Copy Update) 2023.08.09
- Linux Networking Control with C language, Golang (Netfilter, Netlink) 2023.03.03
- IPv6 개요, Ubuntu의 IPv6 주소 설정 방법 2022.12.28
- Hugepage 설정 절차 2022.08.02
- Linux, Windows CPU Memory 사용량 계산 (Go Lang) 2022.07.29
- Linux CPU Memory Stress Test (과부하 만들기) 2022.07.14
Linux에서 즐길만한 Game 프로그램 모음
Linux Kernel Source 분석 자료 및 동영상 강의 모음
"커널연구회"의 자료를 참고!
https://www.kernel.bz/blogPost/kernel-mov-list
http://www.iamroot.org/xe/index.php?mid=Study&document_srl=215076
'Ubuntu' 카테고리의 다른 글
Ubuntu 24.04 한글 입력기 설정 (한영 변환 설정) (0) | 2024.05.03 |
---|---|
Ubuntu 24.04 (Noble Numbat) 설치 (0) | 2024.04.26 |
Linux Kernel / RCU (Read-Copy Update) (0) | 2023.08.09 |
Linux OS(Ubuntu) Hardware 정보 조회 명령 (inxi) (0) | 2023.05.19 |
Ubuntu 22.04 OS에서 netplan으로 VLAN 설정 (6) | 2023.05.18 |
Linux Kernel / RCU (Read-Copy Update)
참고 문서:
"문c 블로그 - RCU(Read Copy Update)"
http://jake.dothome.co.kr/rcu/
참고 문서:
"리눅스 커널 RCU 이해 / 커널연구회"
https://kernel.bz/boardPost/118679/20
'Ubuntu' 카테고리의 다른 글
Ubuntu 24.04 (Noble Numbat) 설치 (0) | 2024.04.26 |
---|---|
Linux Kernel Source 분석 자료 및 동영상 강의 모음 (0) | 2023.08.09 |
Linux OS(Ubuntu) Hardware 정보 조회 명령 (inxi) (0) | 2023.05.19 |
Ubuntu 22.04 OS에서 netplan으로 VLAN 설정 (6) | 2023.05.18 |
Ubuntu 22.04 부팅 모드 설정 (Text or Graphical mode) (0) | 2023.05.18 |
Linux Networking Control with C language, Golang (Netfilter, Netlink)
C language, Go(Golang), Netfilter, Netlink를 이용하여 Linux network을 제어하고 모니터링하는 방법을 알아보자~
개념 이해하기: Netfilter hooks into Linux networking packet flows
The following schematic shows packet flows through Linux networking:
Linux Netfilter + C example code
참고 문서: https://pr0gr4m.github.io/linux/kernel/netfilter/
이론 설명과 함께 잘 동작하는 예시가 있어서 쉽게 이해할 수 있다.
아래는 위 블로그의 끝 부분에 있는 HTTP Traffic만 선별하여 Drop하는 예제 코드인데,
그냥 이 예제 코드만 봐도 이해할 수 있을 것이다.
http_netfilter.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/netdevice.h>
static unsigned int hook_http(void *priv,
struct sk_buff *skb, const struct nf_hook_state *state)
{
struct iphdr *iph;
struct tcphdr *th;
char *data = NULL;
int length = 0;
if (!skb)
return NF_ACCEPT;
iph = ip_hdr(skb);
if (iph->protocol == IPPROTO_TCP) {
th = tcp_hdr(skb);
length = skb->len - iph->ihl * 4 - th->doff * 4;
if (length <= 4)
return NF_ACCEPT;
data = kzalloc(length, GFP_KERNEL);
memcpy(data, (unsigned char *)th + th->doff * 4, length);
if (strstr(data, "HTTP") != NULL) {
printk("[Kernel:%s] HTTP Detected\n", __func__);
kfree(data);
return NF_DROP;
}
kfree(data);
}
return NF_ACCEPT;
}
static struct nf_hook_ops *nf_ops = NULL;
static int __init nfilter_init(void)
{
nf_ops = (struct nf_hook_ops *)kzalloc(sizeof(struct nf_hook_ops), GFP_KERNEL);
nf_ops->hook = (nf_hookfn *)hook_http;
nf_ops->pf = PF_INET;
nf_ops->hooknum = NF_INET_LOCAL_IN;
nf_ops->priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, nf_ops);
printk("[Kernel:%s] NFilter Init\n", __func__);
return 0;
}
static void __exit nfilter_exit(void)
{
nf_unregister_net_hook(&init_net, nf_ops);
kfree(nf_ops);
printk("[Kernel:%s] NFilter Exit\n", __func__);
}
module_init(nfilter_init);
module_exit(nfilter_exit);
MODULE_LICENSE("GPL");
Makefile
obj-m += http_netfilter.o
KDIR := /lib/modules/$(shell uname -r)/build
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
CC := gcc
%.c%:
${CC} -o $@ $^
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
rm -f ${TARGETS}
Build & Test
##
## HTTP Server 장비에서 아래 명령을 수행.
##
$ make
$ sudo insmod http_netfilter.ko
$
---
##
## 다른 PC에서 아래와 같이 HTTP Traffic을 발생시켜본다.
##
$ curl -v http://my-test.server.domain/
* Trying my-test.server.domain:80...
* Connected to my-test.server.domain port 80 (#0)
> GET / HTTP/1.1
> Host: my-test.server.domain
> User-Agent: curl/7.77.0
> Accept: */*
> ##
## TCP Session만 수립될 뿐,
## 실제 HTTP Response 패킷을 받지 못해서 이 상태로 계속 남아있다가 Timed out 처리된다.
##
* Recv failure: Operation timed out
* Closing connection 0
curl: (56) Recv failure: Operation timed out
$
---
##
## HTTP Server 장비에서 아래 명령을 수행.
##
$ dmesg --color --follow
... 중간 생략 ..
[264707.035282] [Kernel:hook_http] HTTP Detected
[264711.387549] [Kernel:hook_http] HTTP Detected
... 중간 생략 ..
Netlink for C language
Wikipedia
Netlink Protocol Library Suite (libnl)
Core Library Developer's Guide (libnl)
Routing Library Developer's Guide (libnl-route)
Example Collection
- https://medium.com/thg-tech-blog/on-linux-netlink-d7af1987f89d
- https://olegkutkov.me/2018/02/14/monitoring-linux-networking-state-using-netlink/
위 문서를 읽고 나서, 아래 예제를 테스트하면서 이해하기.
$ cat detect_chg_event.c
/**
* How to build
* $ gcc -o detect_chg_event detect_chg_event.c
* How to run
* $ ./detect_chg_event
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
static int
create_sock (const char *nic)
{
struct sockaddr_nl addr;
int sock;
memset (&addr, 0, sizeof (addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
sock = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sock < 0)
{
fprintf (stderr, "failed to open NETLINK_ROUTE socket for %s - %s(%d)",
nic, strerror (errno), errno);
return -1;
}
if (bind (sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
fprintf (stderr, "failed to bind NETLINK_ROUTE socket for %s - %s(%d)",
nic, strerror (errno), errno);
close (sock);
return -1;
}
return sock;
}
/**
* NOTE: Cheeck if NIC status is changed
*/
static int
ip_changed (int sock,
const char *nic)
{
struct nlmsghdr *nlh;
char buffer[4096];
int len;
int idx;
int found;
len = recv (sock, buffer, sizeof (buffer), 0);
if (len <= 0)
{
fprintf (stderr, "NETLINK_ROUTE socket recv() failedn");
return -1;
}
printf("\n %s %s(%d) Receive message from raw socket \n",
__func__, __FILE__, __LINE__);
found = 0;
idx = if_nametoindex (nic);
printf("\n %s %s(%d) Index of %s: %d \n",
__func__, __FILE__, __LINE__, nic, idx);
for ( nlh = (struct nlmsghdr *) buffer;
NLMSG_OK (nlh, len);
nlh = NLMSG_NEXT (nlh, len))
{
if (nlh->nlmsg_type == NLMSG_DONE)
break;
if (nlh->nlmsg_type == NLMSG_ERROR)
continue;
if (!(NLMSG_OK (nlh, len)))
continue;
printf("\n %s %s(%d) Netlink MSG Type: %d\n",
__func__, __FILE__, __LINE__, nlh->nlmsg_type);
/*
* NOTE:
* RTM_NEWADDR, RTM_NEWLINK 에 관한 정의는 rtnetlink.h 파일에서 확인할 수 있다.
* - /usr/include/linux/rtnetlink.h
*/
switch (nlh->nlmsg_type)
{
case RTM_NEWADDR:
{
struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA (nlh);
if (ifa->ifa_index == idx)
found = 1;
}
break;
case RTM_NEWLINK:
{
struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA (nlh);
if (ifi->ifi_index == idx)
found = 1;
}
break;
default:
break;
}
}
return found;
}
static int
get_nic_addr ( const char *nic,
struct ifaddrs *ifaddr,
int wanted_family,
char *host,
int host_len,
int *active)
{
struct ifaddrs *ifa;
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
int family;
int s;
if (ifa->ifa_addr == NULL)
continue;
if (strcmp (ifa->ifa_name, nic))
continue;
/* Skip unwanted families. */
family = ifa->ifa_addr->sa_family;
if (family != wanted_family)
continue;
*active = (ifa->ifa_flags & IFF_RUNNING) ? 1 : 0;
s = getnameinfo ( ifa->ifa_addr,
family == AF_INET ? sizeof (struct sockaddr_in) :
sizeof (struct sockaddr_in6),
host,
host_len,
NULL,
0,
NI_NUMERICHOST);
if (s != 0)
{
fprintf (stderr, "failed to getnameinfo() for '%s - %s(%d)",
ifa->ifa_name, strerror (errno), errno);
continue;
}
/* Get the address of only the first network interface card. */
return 1;
}
return 0;
}
static void
print_ip (const char *nic)
{
struct ifaddrs *ifaddr;
char addr[NI_MAXHOST];
int active;
printf("\n %s(%d) nic: %s \n",
__FILE__, __LINE__, nic);
if (getifaddrs (&ifaddr) == -1)
{
fprintf (stderr, "failed to getifaddrs() - %s(%d)", strerror (errno), errno);
return;
}
// NOTE: IPv4
if (!get_nic_addr (nic, ifaddr, AF_INET, addr, sizeof (addr), &active))
{
// If IPv4 configuration is not available,
// then try to get the Ipv6 configuration.
printf("\n %s(%d) nic: %s addr: %s active: %d \n",
__FILE__, __LINE__, nic, addr, active);
// NOTE: IPv6
if (!get_nic_addr (nic, ifaddr, AF_INET6, addr, sizeof (addr), &active))
{
// Nothing to do.
strcpy (addr, "127.0.0.1");
active = 0;
}
} else {
printf("\n %s(%d) nic: %s addr: %s active: %d \n",
__FILE__, __LINE__, nic, addr, active);
}
freeifaddrs (ifaddr);
printf("\n %s %s(%d) %s is %s (link %s) \n",
__func__, __FILE__, __LINE__,
nic, addr, active ? "active" : "inactive");
}
int
main (void)
{
// FIXME: enp7s0 --> my machine's network interface name
char *nic = "enp7s0";
int sock;
print_ip (nic);
sock = create_sock (nic);
if (sock < 0)
return -1;
while (1)
{
int ret;
ret = ip_changed (sock, nic);
if (ret < 0)
return -1;
if (ret)
print_ip (nic);
printf("\n\n %s %s(%d) END OF LOOP \n\n\n",
__func__, __FILE__, __LINE__);
}
close (sock);
return 0;
}
$
$ gcc -o detect_chg_event detect_chg_event.c
$ ./detect_chg_event
ip_changed detect_chg_event.c(73) Receive message from raw socket
ip_changed detect_chg_event.c(79) Index of enp7s0: 2
ip_changed detect_chg_event.c(93) Netlink MSG Type: 16
detect_chg_event.c(181) nic: enp7s0
detect_chg_event.c(205) nic: enp7s0 addr: 10.1.4.51 active: 1
print_ip detect_chg_event.c(211) enp7s0 is 10.1.4.51 (link active)
main detect_chg_event.c(239) END OF LOOP
...
...
위 예제에서 detect_chg_event 명령을 실행시켜 놓고, 아래와 같이 명령을 실행해본다.
$ ifconfig enp7s0 mtu 1501
$ ifconfig enp7s0 mtu 1500
$ ifconfig enp7s0 down
$ ifconfig enp7s0 up
detect_chg_event 예제 앱이 enp7s0 장치의 상태 변화를 감지해서 터미널에 감지한 내용을 출력해줄 것이다.
Netlink library for go
https://github.com/vishvananda/netlink
https://tomdnetto.net/post/linux_networking_from_go_nftables
https://tomdnetto.net/post/advanced_nftables_with_go
'Network' 카테고리의 다른 글
tcpdump 명령으로 tcp syn, rst 패킷 확인 (0) | 2023.07.25 |
---|---|
10G L3 Switch 장비 추천 (NEXTU 3424GL3-10G) (3) | 2023.04.13 |
CISCO ACI(Application Centric Infra), APIC and Kubernetes (0) | 2022.07.19 |
GNS3, CISCO Switch 명령 모음 및 동영상 강의 (0) | 2022.07.02 |
GNS3 사용을 위한 CISCO IOS 구하는 방법 (0) | 2022.07.01 |
IPv6 개요, Ubuntu의 IPv6 주소 설정 방법
작성일: 2023년 7월 16일
IPv6 스터디하면서 참고했던 자료나 기억할 것을 여기에 기록하기
IPv6 주소 표기
- 128 bit
- 16 bit 씩 8자리로 구성. 각 자리는 콜론으로 구분
- 앞 64 bit는 network address, 뒤 64 bit는 장비의 network interface address
(network address는 64 bit 길이가 아니어도 된다. 더 크거나 더 작아도 된다.) - IPv6 주소 예시
2001:db8:0:1::a00:1 |
2001:db8:0:1::a00:1/64 |
IPv4, IPv6 Header 구조 비교
IPv6 확장 Header
IPv6 통신 방식 (Network Node 간 통신 방식)
IPv6 통신 방식 | Description |
Unicast | 1:1 통신 (특정 1개 Node간 통신) |
Multicast | 1:N 또는 N:M 노드간 통신 |
Anycast | 전세계에 동일한 Anycast address를 가진 node 중에서 가장 통신 cost가 적게 되는 node를 선택하여 통신 |
IPv6 주소 종류
Unicast Address 종류
Unicast Address 종류 | Description |
Global Unicast Address | - Public IP Address - IPv4에 비유하자면 Public IP address 같은 용도로 사용하는 IPv6 address - 2000::/3 - 각 기관별 IPv6 할당 가능한 주소 값을 아래 할당 표를 열람 https://www.iana.org/assignments/ipv6-unicast-address-assignments/ipv6-unicast-address-assignments.xhtml - 국내 IPv6 관리 대행자별 IPv6 주소 목록 https://krnic.kisa.or.kr/jsp/business/management/isCurrentIpv6.jsp |
Link-Local Unicast Address | - Link 내에서만 사용 가능한 Address. - 예를 들어, Router-A가 Link-Local Unicast Address를 Destination Address로 하는 패킷을 받으면 다른 Network로 Forward하지 않는다. - 그래서 1개 Link 구간에서 Network control message를 전달할 때, 이 주소를 사용한다. - 만약, 1개 물리적 포트에 Global Unicast Address와 Link-Local Unicast Address를 모두 설정한 경우라면 Global Unicast Address 값을 변경하는 경우에도 Link-Local Unicast Address로 통신이 가능하다. - 1개 Link 내에서만 통신이 가능하기 때문에 ICMPv6를 이용한 외부에서의 공격을 원천적으로 막을 수 있다. - IPv4의 자동 설정 IP 주소인 169.254.x.x에 유사한 목적으로 사용됨 - FE80::/10 |
Unique Local Unicast Address | - IPv4에 비유하자면 Private network address(10.0.0.0 172.16.0.0 192.168.0.0) 같은 IPv6 address. - 예를 들어, 1개 회사 빌딩 내부에서의 통신, 1개 대학 캠퍼스 내부에서의 통신만 할 때 이 주소를 사용한다. - FC00::/7 |
예시: Global Unicast Address
예시: Link Local Unicast Address
Multicast Address
ff00::/8 - IPv6 멀티캐스트를 위한 주소공간이다. IPv4에서 제공했던 브로드캐스트는 IPv6에서는 더 이상 지원되지 않으며, IPv6에서는 대신 멀티캐스트를 사용해야 한다.
Multicast Address 종류 | Description |
Solicited Node Multicast | - 이더넷 환경에서 Neighbor 탐색 과정(IPv4의 ARP 과정과 유사)에 사용 - Auto configuration 과정에서 DAD(Duplicate Address Detection) 과정을 거칠 때 사용 - Solicited Node Multicast 주소의 112비트 부분은 FF02::1:FF로 정해져 있으며 나머지 24비트는 IPv6의 최하위 24비트 부분을 차용하여 사용 (예: IPv6 주소-2001:1:1:1::1234:5678 → Solicited node multicast 주소- FF02::1:FF34:5678) |
All Node Multicast | - 노드의 모든 IPv6 호스트와 라우터들이 소속되어 있는 그룹 - All node multicast주소는 FF02::1 사용 |
All Router Multicast | - 모든 IPv6 라우터들이 소속되어 있는 그룹 - All router multicast 주소는 FF02::2 사용 |
IPv6 Multicast Group
Anycast Address
Anycast 통신은 ‘1:가장 가까운 1’간의 통신방식이라고 정의할 수 있다.
동일한 주소를 가지는 여러 목적지 장비들 중 출발지 장비와 가장 가까운 장비가 응답을 하는 통신방식이다.
이러한 통신방식은 멀티캐스트와 유사하지만 멀티캐스트의 경우 동일 그룹에 소속된 장비들이 응답을 하는 반면, 애니캐스트의 경우는 동일 주소를 가지는 장비들 중 가장 가까운 장비 하나만 응답을 한다는 차이가 있다.
IPv4-mapped IPv6 addresses
주소 표현 예시 | ::FFFF:129.144.52.38 |
명령 사용 예시 | $ ping ::ffff:192.168.139.50 $ ping ::ffff:c0a8:8b32 |
IPv6 Address Scope 개념
IPv6 Address Scope 종류 | Description |
Global Scope | IPv6로 통신할 수 있는 모든 영역 (예: 지구 전체) |
Link-Local Scope | Broadcast domain 또는 Network interface가 직접 연결된 Link 영역 |
Site-Local Scope | [ 내 생각: 실제로 이 Site-Local Scope 개념이 사용되는지 모르겠음 ] [ 내 생각: Site-Local Address는 2004년 10월 RFC3897에서 폐기되었음. 아마 Site-Local Scope의 모호성 때문에 폐기한 것이 아닌가 추정해봄 ] 한 조직의 관리자가 관리하는 Network 영역 (예: 특정 통신사, 회사, 호텔, 정부청사 같은 영역) 네트워크 관리자가 Site-Local Scope을 설정하는 것이므로 Scope의 경계를 설명하기 애매하다. 예를 들어, 네트워크 관리자가 A회사와 B호텔을 1개의 Site-Local Scope으로 지정하면, 의도하지 않게 Networking이 되는 상황이 발생 |
국내 IPv6 관리대행자별 IPv6 주소 목록 (2023.07.17 현재)
기관명 | 영문서비스명 | 시작주소 | 프리픽스 | 개수 | 할당일 |
에이비클 | ABCLE | 2001:0EF8:: | /32 | 65536 | 20040524 |
(주)아프리카티비 | AFREECATV | 2406:6600:: | /32 | 65536 | 20110124 |
(주)엘지유플러스 | BORANET | 2001:0270:: | /32 | 65536 | 20000908 |
씨디네트웍스 | CDNETWORKS | 2401:C500:: | /32 | 65536 | 20110830 |
(주) 씨엠비 | CMBI-NETDJ | 2403:6500:: | /32 | 65536 | 20120326 |
주식회사 씨엠비영등포방송 | CMBI-NETHK | 2404:2300:: | /32 | 65536 | 20120607 |
주식회사 씨엠비광주방송 | CMBKWANGJUNET | 2406:B000:: | /32 | 65536 | 20080324 |
주식회사 씨엠비광주방송 | CMBKWANGJUNET | 2402:7000:: | /32 | 65536 | 20080403 |
(주)다우기술 | DAOU | 2403:3E00:: | /32 | 65536 | 20100707 |
디지털엣지코리아 | DEK-NET | 2400:FD60:: | /32 | 65536 | 20230512 |
삼정데이타서비스(주) | DIRECT-HOSTING | 2403:3700:: | /32 | 65536 | 20120307 |
주식회사 딜라이브 | DLIVE | 2402:BE00:: | /32 | 65536 | 20100608 |
드림라인(주) | DREAMX | 2001:0C48:: | /32 | 65536 | 20020812 |
두루안 | DURUAN | 2001:0390:: | /32 | 65536 | 20020207 |
(주)이호스트아이씨티 | EHOSTICT | 2407:0B00:: | /32 | 65536 | 20130529 |
(주)가비아 | GABIA-IP | 2401:9EC0:: | /32 | 65536 | 20170811 |
한국케이블TV푸른방송(주) | GCS | 2407:2000:: | /32 | 65536 | 20070716 |
엔티티코리아 주식회사 | GIN | 2001:0D38:: | /32 | 65536 | 20030515 |
하이온넷(주) | HAIONNET | 2404:0800:: | /32 | 65536 | 20080912 |
주식회사 에이치씨엔 | HCN | 2001:0EA0:: | /32 | 65536 | 20040329 |
주식회사 하이라인닷넷 | HINETWORKS | 2407:B200:: | /32 | 65536 | 20110314 |
호스트웨이아이디씨(주) | HOSTWAY | 2406:AD00:: | /32 | 65536 | 20130410 |
효성ITX | HYOSUNGCDN | 2407:3500:: | /32 | 65536 | 20130618 |
인천국제공항공사 | IIAC | 2400:A0A0:: | /32 | 65536 | 20220816 |
주식회사 아이네트호스팅 | INET | 2001:0F48:: | /32 | 65536 | 20040806 |
JCN울산중앙방송(주) | JCN | 2402:1A00:: | /32 | 65536 | 20100506 |
주식회사 제이엔디통신 | JNDINFO | 2402:6100:: | /32 | 65536 | 20111101 |
금강방송주식회사 | KCNNET | 2403:6300:: | /32 | 65536 | 20120326 |
한국데이타 | KDATA | 2406:6800:: | /32 | 65536 | 20090402 |
(주)한국데이터통신 | KDTIDC | 2405:3500:: | /32 | 65536 | 20120921 |
(주)엘지유플러스 | KIDC | 2001:0ED0:: | /32 | 65536 | 20040418 |
주식회사 케이아이엔엑스 | KINXINC | 2001:07FA:0008:: | /48 | 1 | 20020402 |
주식회사 케이아이엔엑스 | KINXINC | 2401:2700:: | /32 | 65536 | 20110615 |
한국지능정보사회진흥원 | KOREN | 2407:C000:: | /32 | 65536 | 20070522 |
한국지능정보사회진흥원 | KOREN | 2406:D000:: | /32 | 65536 | 20080204 |
주식회사 케이티 | KORNET | 2001:0220:: | /32 | 65536 | 19991006 |
주식회사 케이티 | KORNET | 2001:0280:: | /32 | 65536 | 20000927 |
주식회사 케이티 | KORNET | 2001:02B0:: | /32 | 65536 | 20010102 |
주식회사 케이티 | KORNET | 2001:0E60:: | /32 | 65536 | 20040213 |
주식회사 케이티 | KORNET | 2001:0EA8:: | /32 | 65536 | 20040331 |
주식회사 케이티 | KORNET | 2001:0EF0:: | /32 | 65536 | 20040524 |
주식회사 케이티 | KORNET | 2400:0000:: | /20 | 268435456 | 20050601 |
재단법인 한국교육전산망협의회 | KREN | 2001:0E70:: | /32 | 65536 | 20040317 |
재단법인 한국교육전산망협의회 | KREN | 2402:0000:: | /22 | 67108864 | 20061107 |
한국과학기술정보연구원 | KREONet | 2001:0320:: | /32 | 65536 | 20010823 |
(주)한국무역정보통신 | KTNET | 2001:0EB8:: | /32 | 65536 | 20040407 |
주식회사 엘지헬로비전 | LG-HELLOVISION | 2405:7B00:: | /32 | 65536 | 20121017 |
(주) 엘지씨엔에스 | LG-NET | 2400:3300:: | /32 | 65536 | 20110407 |
(주)엘지유플러스 | LGTELECOM | 2001:4430:: | /32 | 65536 | 20050706 |
엘엑스(IP주소 인터넷 서비스 업체) | LXN | 2402:3100:: | /32 | 65536 | 20111012 |
네이버클라우드 주식회사 | NBP-NET | 2402:DE00:: | /32 | 65536 | 20110107 |
(주)비트넷 | NETIP | 2405:5F00:: | /32 | 65536 | 20121010 |
엔에이치엔클라우드 | NHNCLOUD-NET | 2405:D880:: | /32 | 65536 | 20160630 |
남인천방송(주) | NIBDIGITAL | 2407:B800:: | /32 | 65536 | 20090520 |
피란하시스템즈 | PIRANHA | 2402:F400:: | /32 | 65536 | 20100113 |
(주)엘지유플러스 | PUBNETPLUS | 2001:0E78:: | /32 | 65536 | 20040317 |
삼성에스디에스(주) | SAMSUNGSDS | 2001:0330:: | /32 | 65536 | 20010920 |
삼성에스디에스(주) | SAMSUNGSDS | 2404:0180:: | /28 | 1048576 | 20060829 |
(주)에스비코리아 | SBKOREACORP | 2400:FDA6:: | /32 | 65536 | 20230512 |
세종텔레콤 주식회사 | SHINBIRO | 2001:03A8:: | /32 | 65536 | 20020402 |
세종텔레콤 주식회사 | SHINBIRO | 2001:0CF0:: | /32 | 65536 | 20030122 |
SK(주) | SK-NET | 2405:8600:: | /32 | 65536 | 20101202 |
에스케이텔레콤(주) | SK-TELECOM-NET | 2001:02D8:: | /32 | 65536 | 20010406 |
에스케이텔레콤(주) | SK-TELECOM-NET | 2001:0F28:: | /32 | 65536 | 20040708 |
에스케이텔링크주식회사 | SKTelink | 2001:0E98:: | /32 | 65536 | 20040329 |
케이디디아이코리아(주) | TELEHOUSE-SEOUL | 2400:1800:: | /32 | 65536 | 20090128 |
유엘네트웍스 | ULNETWORKS | 2405:4300:: | /32 | 65536 | 20120925 |
주식회사 넥스지 | VAAN | 2402:5800:: | /32 | 65536 | 20080703 |
주식회사 브이토피아 | VTOPIA | 2406:D700:: | /32 | 65536 | 20130502 |
(주)엘지유플러스 | Xpeed | 2406:5900:: | /32 | 65536 | 20130306 |
에스케이브로드밴드주식회사 | broadNnet | 2001:0290:: | /32 | 65536 | 20001030 |
에스케이브로드밴드주식회사 | broadNnet | 2001:0378:: | /32 | 65536 | 20011218 |
에스케이브로드밴드주식회사 | broadNnet | 2001:0EE8:: | /32 | 65536 | 20040517 |
에스케이브로드밴드주식회사 | broadNnet | 2001:44D0:: | /28 | 1048576 | 20051110 |
에스케이브로드밴드주식회사 | broadNnet | 2401:4000:: | /32 | 65536 | 20070316 |
에스케이브로드밴드주식회사 | broadNnet | 2406:4000:: | /32 | 65536 | 20070316 |
에스케이브로드밴드주식회사 | broadNnet | 2401:A800:: | /32 | 65536 | 20080602 |
에스케이브로드밴드주식회사 | broadNnet | 2405:5800:: | /32 | 65536 | 20081020 |
에스케이브로드밴드주식회사 | broadNnet | 2407:6500:: | /32 | 65536 | 20130705 |
에스케이브로드밴드주식회사 | broadNnet | 2407:6700:: | /32 | 65536 | 20130705 |
에스케이브로드밴드주식회사 | broadNnet | 2407:9100:: | /32 | 65536 | 20130718 |
에스케이브로드밴드주식회사 | broadNnet | 2407:C700:: | /32 | 65536 | 20130822 |
에스케이브로드밴드주식회사 | broadNnet | 2400:4980:: | /32 | 65536 | 20131106 |
에스케이브로드밴드주식회사 | broadNnet | 2400:4780:: | /32 | 65536 | 20131111 |
에스케이브로드밴드주식회사 | broadNnet | 2400:9E80:: | /32 | 65536 | 20140213 |
에스케이브로드밴드주식회사 | broadNnet | 2400:9F80:: | /32 | 65536 | 20140213 |
에스케이브로드밴드주식회사 | broadNnet | 2400:A580:: | /32 | 65536 | 20140218 |
에스케이브로드밴드주식회사 | broadNnet | 2400:E180:: | /32 | 65536 | 20140415 |
(주)이지오스 | eGIOSNET | 2405:C000:: | /32 | 65536 | 20070509 |
Linux (Ubuntu)에서 IPv6 Address 사용
IPv6 Address 설정하기 (nmcli 명령 사용)
## ip addr 명령으로 설정
## a) IPv6 주소 설정
$ ip -6 addr add 2001:db8:0:1::a00:2/64 dev enp1s0
## b) IPv6 주소 삭제
$ ip -6 addr del 2001:db8:0:1::a00:2/64 dev enp1s0
## c) IPv6 주소 확인
$ ip -6 addr show dev enp1s0
## nmcli 명령으로 설정
## a) Network device list 출력
$ nmcli dev
## b) IPv6 주소 설정
$ nmcli con mod ens0 ipv6.address 2001:db8:0:1::a00:1/64 ipv6.gateway 2001:db8:0:1::1
참고 문서 https://www.lesstif.com/system-admin/centos-nmcli-ip-static-ip-98926807.html
IPv6 Address 설정하기 (Gnome GUI 설정 화면 사용)
아래 예시 화면처럼 [IPv6] 설정 탭에서 Address, Prefix, Gateway를 설정한다.
Web Browser로 IPv6 주소의 웹 페이지 조회하기
아래 예제처럼 주소창에 IPv6 주소값을 입력하고 테스트해본다.
http://[2001:db8:0:1::a00:1]:8080/
curl 명령으로 동일하게 테스트할 수 있다. (아래 예제를 참고)
$ curl http://[2001:db8:0:1::a00:1]:8080/
Hello from example application. (written by Andrew)
$
CURL 명령으로 IPv6 주소 확인하기 (Global scope address)
## 이 장비의 Network port에 설정된 IPv6 주소 열람하기
$ ip -6 addr
## IPv6 주소 중에서 Global scope 주소만 열람하기
$ ip -6 addr show scope global
## 나의 NAT 장비의 IPv6 인터넷 주소 확인하기
## (참고: NAT에 IPv6가 설정되지 않았으면, IPv4 주소가 출력된다)
$ dig -6 TXT +short o-o.myaddr.l.google.com @ns1.google.com
$ dig -t aaaa +short myip.opendns.com @resolver1.opendns.com
$ curl -6 https://ifconfig.co
$ curl -6 https://ipv6.icanhazip.com
$ ssh -6 sshmyip.com
IPv4 to IPv6 주소 변환하기
참고 문서:
KRNIC 스터디 자료
https://xn--3e0bx5euxnjje69i70af08bea817g.xn--3e0b707e/jsp/resources/vsix/icmp.jsp
NDP 설명 영상
https://www.youtube.com/watch?v=A3LFt7CHpgs
https://www.minzkn.com/moniwiki/wiki.php/IPv6
https://en.wikipedia.org/wiki/IPv6_address
'IT General' 카테고리의 다른 글
악성코드 분석 - YouTube 영상 모음 (0) | 2023.03.20 |
---|---|
mariaDB, MySQL System Variables 설정 (성능 튜닝을 위해) (0) | 2023.02.21 |
[용어] air-gapped / 연결이 끊긴 폐쇄망 / 단절망 / 독립망 / 고립망 (0) | 2022.12.21 |
Block Chain, Bitcoin, Etherium 등 관련 URL 목록 (0) | 2022.12.19 |
Block Chain(블록 체인), 스마트계약(Smart Contract), NTF 관련 자료 모음 (0) | 2022.11.30 |
Hugepage 설정 절차
아래 예시는 Linux OS에 Hugepage를 적용하는 절차이다.
##
## /etc/default/grub 파일에서
## default_hugepagesz, hugepagesz, hugepages, transparent_hugepage
## 항목을 추가 설정한다.
## (아래 예시를 참고)
##
$ cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet default_hugepagesz=1GB hugepagesz=1G hugepages=320 transparent_hugepage=never"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
$
##
## 위와 같이 /etc/default/grub 파일을 수정하고,
## grub2 명령으로 설정을 적용한다.
##
## Case: UEFI Mode
$ grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
## Case: Legacy BIOS Mode
$ grub2-mkconfig -o /boot/grub2/grub.cfg
##
## 위와 같이 설정 작업을 마무리했으면, OS를 Reboot하여 설정을 반영한다.
##
$ reboot
'CentOS' 카테고리의 다른 글
스터디할 때 참고할 만한 Web Docs (0) | 2022.08.12 |
---|---|
YUM 또는 DNF Repository 추가 방법 (0) | 2022.06.22 |
OpenStack, OCI, AWS 에서 VM Instance를 위한 UserData 설정 (init-cloud 스크립트) (0) | 2022.06.21 |
CPU Pinning 예제 코드 (0) | 2022.06.17 |
Install Ansible AWX (version 17.1.0) (0) | 2021.11.16 |
Linux, Windows CPU Memory 사용량 계산 (Go Lang)
Go Language로 특정 Process의 CPU, Memory 사용량을 계산하고 싶다면,
아래의 코드를 Build해서 사용하면 된다.
참고: Linux, MacOS, Unix, Windows 모두 동작하는 코드임.
// Filename: proc_usage.go
package main
import (
"errors"
"fmt"
"io/ioutil"
"math"
"os/exec"
"path"
"runtime"
"strconv"
"strings"
"sync"
)
const (
statTypePS = "ps"
statTypeProc = "proc"
)
// SysInfo will record cpu and memory data
type SysInfo struct {
CPU float64
Memory float64
}
// Stat will store CPU time struct
type Stat struct {
utime float64
stime float64
cutime float64
cstime float64
start float64
rss float64
uptime float64
}
type fn func(int) (*SysInfo, error)
var fnMap map[string]fn
var platform string
var history map[int]Stat
var historyLock sync.Mutex
var eol string
// Linux platform
var clkTck float64 = 100 // default
var pageSize float64 = 4096 // default
func init() {
platform = runtime.GOOS
if eol = "\n"; strings.Index(platform, "win") == 0 {
platform = "win"
eol = "\r\n"
}
history = make(map[int]Stat)
fnMap = make(map[string]fn)
fnMap["darwin"] = wrapper("ps")
fnMap["sunos"] = wrapper("ps")
fnMap["freebsd"] = wrapper("ps")
fnMap["openbsd"] = wrapper("proc")
fnMap["aix"] = wrapper("ps")
fnMap["linux"] = wrapper("proc")
fnMap["netbsd"] = wrapper("proc")
fnMap["win"] = wrapper("win")
if platform == "linux" || platform == "netbsd" || platform == "openbsd" {
initProc()
}
}
func initProc() {
clkTckStdout, err := exec.Command("getconf", "CLK_TCK").Output()
if err == nil {
clkTck = parseFloat(formatStdOut(clkTckStdout, 0)[0])
}
pageSizeStdout, err := exec.Command("getconf", "PAGESIZE").Output()
if err == nil {
pageSize = parseFloat(formatStdOut(pageSizeStdout, 0)[0])
}
}
func wrapper(statType string) func(pid int) (*SysInfo, error) {
return func(pid int) (*SysInfo, error) {
return stat(pid, statType)
}
}
func formatStdOut(stdout []byte, userfulIndex int) []string {
infoArr := strings.Split(string(stdout), eol)[userfulIndex]
ret := strings.Fields(infoArr)
return ret
}
func parseFloat(val string) float64 {
floatVal, _ := strconv.ParseFloat(val, 64)
return floatVal
}
func statFromPS(pid int) (*SysInfo, error) {
sysInfo := &SysInfo{}
args := "-o pcpu,rss -p"
if platform == "aix" {
args = "-o pcpu,rssize -p"
}
stdout, _ := exec.Command("ps", args, strconv.Itoa(pid)).Output()
ret := formatStdOut(stdout, 1)
if len(ret) == 0 {
return sysInfo, errors.New("Can't find process with this PID: " + strconv.Itoa(pid))
}
sysInfo.CPU = parseFloat(ret[0])
sysInfo.Memory = parseFloat(ret[1]) * 1024
return sysInfo, nil
}
func statFromProc(pid int) (*SysInfo, error) {
sysInfo := &SysInfo{}
uptimeFileBytes, err := ioutil.ReadFile(path.Join("/proc", "uptime"))
if err != nil {
return nil, err
}
uptime := parseFloat(strings.Split(string(uptimeFileBytes), " ")[0])
procStatFileBytes, err := ioutil.ReadFile(path.Join("/proc", strconv.Itoa(pid), "stat"))
if err != nil {
return nil, err
}
splitAfter := strings.SplitAfter(string(procStatFileBytes), ")")
if len(splitAfter) == 0 || len(splitAfter) == 1 {
return sysInfo, errors.New("Can't find process with this PID: " + strconv.Itoa(pid))
}
infos := strings.Split(splitAfter[1], " ")
stat := &Stat{
utime: parseFloat(infos[12]),
stime: parseFloat(infos[13]),
cutime: parseFloat(infos[14]),
cstime: parseFloat(infos[15]),
start: parseFloat(infos[20]) / clkTck,
rss: parseFloat(infos[22]),
uptime: uptime,
}
_stime := 0.0
_utime := 0.0
historyLock.Lock()
defer historyLock.Unlock()
_history := history[pid]
if _history.stime != 0 {
_stime = _history.stime
}
if _history.utime != 0 {
_utime = _history.utime
}
total := stat.stime - _stime + stat.utime - _utime
total = total / clkTck
seconds := stat.start - uptime
if _history.uptime != 0 {
seconds = uptime - _history.uptime
}
seconds = math.Abs(seconds)
if seconds == 0 {
seconds = 1
}
history[pid] = *stat
sysInfo.CPU = (total / seconds) * 100
sysInfo.Memory = stat.rss * pageSize
return sysInfo, nil
}
func stat(pid int, statType string) (*SysInfo, error) {
switch statType {
case statTypePS:
return statFromPS(pid)
case statTypeProc:
return statFromProc(pid)
default:
return nil, fmt.Errorf("Unsupported OS %s", runtime.GOOS)
}
}
// GetStat will return current system CPU and memory data
func GetStat(pid int) (*SysInfo, error) {
sysInfo, err := fnMap[platform](pid)
return sysInfo, err
}
// Filename: main.go
package main
import (
"os"
"fmt"
"time"
"strconv"
)
func main() {
myPid, _ := strconv.Atoi(os.Args[1])
for i:= 0; i < 100; i++ {
sysInfo, _ := GetStat(myPid)
fmt.Println("CPU Usage :", sysInfo.CPU)
fmt.Println("Mem Usage(RSS):", sysInfo.Memory)
time.Sleep(5 * time.Second)
}
}
위와 같이 Go source code를 모두 작성했다면, 아래처럼 build하고 실행하면 된다.
$ go mod init andrew.space/proc_usage
go: creating new go.mod: module andrew.space/proc_usage
go: to add module requirements and sums:
go mod tidy
$ go mod tidy
$ go build
$ ./proc_usage 4314
CPU Usage : 52.92167225853122
Mem Usage(RSS): 2.018664448e+09
CPU Usage : 39.800000000000004
Mem Usage(RSS): 2.018664448e+09
CPU Usage : 47.30538922366738
Mem Usage(RSS): 2.018664448e+09
...
...
top 명령으로 본 것과 결과가 동일했다.
'Ubuntu' 카테고리의 다른 글
Ubuntu Network 설정 (nmtui, netplan, nm-connection-editor 명령) (0) | 2022.11.24 |
---|---|
Ubuntu 22.04 (24.04) 한글 입력기 설정 (한영 변환 설정) (1) | 2022.11.18 |
Linux CPU Memory Stress Test (과부하 만들기) (0) | 2022.07.14 |
Epoch & Unix Time변환 (Date 변환) (0) | 2022.07.07 |
KVM의 VM에서 Hugepage 사용하기 (0) | 2022.01.13 |
Linux CPU Memory Stress Test (과부하 만들기)
시스템 알람을 발생시키는 테스트를 하거나 Kubernetes의 Horizontal Pod Autoscaler 기능 테스트를 할 때,
CPU 부하를 발생시키는 명령 도구가 있으면 편하다.
아래와 같이 설치하고 테스트하면 된다. (설명은 생략하고, 그냥 따라해보자~)
##
## 설치
##
$ yum install -y stress
$ stress --help
...
##
## 30초 동안 3000ms의 CPU 과부하를 유발하기.
##
$ stress --cpu 3 --timeout 30s
##
## 500MB의 메모리 과부하를 유발하기
## --vm : Worker 개수
## --vm-hang : malloc 실행 후 free하기 전까지 sleep할 시간(초)
##
$ stress --vm 1 --vm-bytes 500M --vm-hang 1
블로그 작성자: sejong.jeonjo@gmail.com
'Ubuntu' 카테고리의 다른 글
Ubuntu 22.04 (24.04) 한글 입력기 설정 (한영 변환 설정) (1) | 2022.11.18 |
---|---|
Linux, Windows CPU Memory 사용량 계산 (Go Lang) (0) | 2022.07.29 |
Epoch & Unix Time변환 (Date 변환) (0) | 2022.07.07 |
KVM의 VM에서 Hugepage 사용하기 (0) | 2022.01.13 |
PCI passthrough on Ubuntu + KVM (0) | 2022.01.12 |