반응형

아래 YouTube 영상에 악성코드 분석한 내용이 A - Z까지 상세히 설명되어 있다.

 

 

https://www.youtube.com/@user-vj3ck2pf2k/videos

 

악분

악성코드 자료를 중점으로 공유하는 채널입니다.

www.youtube.com

 

반응형

 

OVS로 VLAN network를 구성하고 테스트해볼까 생각했는데, 이미 다른 분이 아주 상세하게 테스트한 내용을 잘 적어놓았네 ^^

 

 

https://m.blog.naver.com/love_tolty/222609033937

 

라즈베리파이3에 Open vSwitch(OVS) 설치/OVS 네트워크 구성/ONOS로 직접 Flow Rule 설정하여 VLAN 패킷 제어

자! 지난 포스팅에서는 Mininet기반 가상 네트워크 환경에서 ONOS로 간단히 Host간 통신이 되도록 F...

blog.naver.com

 

반응형

C언어로 Multi thread 구조를 만들다보면 자연스럽게 사용하게 되는 mutex lock과 conditional variable에 관한 예제이다.

 

 

#include "sys/time.h"
#include "sys/types.h"
#include <sys/poll.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define   ITER  30

int                 g_data[ITER];

pthread_cond_t      cond[ITER];
pthread_mutex_t     mutex[ITER];


void* producer(void *data){
    int  rc;
    int  idx = 0;

    while (1) {
        int idx_mod = idx % ITER;
        rc = pthread_mutex_lock(&mutex[idx_mod]);
        g_data[idx_mod] = idx;
#ifdef __STDOUT_PRINT__
        printf("producer.data: %d\n", g_data[idx_mod]);
        fflush(NULL);
#endif
        rc = pthread_cond_signal(&cond[idx_mod]);
        rc = pthread_mutex_unlock(&mutex[idx_mod]);
        poll(0, 0, 1);
        idx++;
    }
}


void* consumer(void *data){
    int  rc;
    int  my_thr_idx = *(int *)data;

    printf("consumer thread idx: %d\n", my_thr_idx);

    while (1) {
        rc = pthread_mutex_lock(&mutex[my_thr_idx]);
        rc = pthread_cond_wait(&cond[my_thr_idx], &mutex[my_thr_idx]);
#ifdef __STDOUT_PRINT__
        printf("comsumer[%d].data: %d\n\n", my_thr_idx, g_data[my_thr_idx]);
        fflush(NULL);
#endif
        rc = pthread_mutex_unlock(&mutex[my_thr_idx]);
    }
}

int main()
{
    //
    // producer thread
    //
    pthread_t    thr_id_prod;
    if (pthread_create(&thr_id_prod, NULL, producer, NULL) != 0) {
        printf("thread create error(%d, %s)\n", errno, strerror(errno));
        return 0;
    }

    poll(0, 0, 1000);

    //
    // consumer thread
    //
    pthread_t    thr_id_cons[ITER];
    int          new_idx[ITER];
    for (int idx=0; idx<ITER; idx++) {
        new_idx[idx] = idx;
        pthread_mutex_init(&mutex[idx], NULL);
        pthread_cond_init(&cond[idx], NULL);
        if (pthread_create(&thr_id_cons[idx], NULL, consumer, (void *) &new_idx[idx]) != 0) {
            printf("thread create error(%d, %s)\n", errno, strerror(errno));
            return 0;
        }
    }

    int status;
    for (int idx=0; idx<ITER; idx++) {
        pthread_join(thr_id_cons[idx], (void **)&status);
    }

    return 0;
}

 

위와 같이 코드를 작성하고, gcc compiler로 실행 파일을 만든다.

 

$ gcc -D__STDOUT_PRINT__ main.c -o my_test_app

$ ./my_test_app

 

 

 

반응형

 

데브시스터즈 Kubernetes 도입 사례

https://www.youtube.com/watch?v=8R4DDEqjc0I 

 

Kubernetes를 어떤 방식으로 활용할까, 도입할까 말까를 고민하고 있다면 위 영상이 도움이 될 것 같다.

 

 

 

Kubernetes 인터넷 강의 / 따배쿠 (따라하면서 배우는 Kubernetes)

기초부터 차근차근 배우고 싶다면, 아래 영상을 처음부터 끈기있게 보면 좋다.

거의 책 한권 읽는 수준이다.

 

https://www.youtube.com/results?search_query=%EB%94%B0%EB%B0%B0%EC%BF%A0 

 

https://www.youtube.com/results?search_query=%EB%94%B0%EB%B0%B0%EC%BF%A0

 

www.youtube.com

 

 

Kubernetes에 관한 전반적인 사용 설명

https://www.youtube.com/@Akbun/videos

 

악분 일상

현재 공부한 것들을 공유하는 채널입니다.

www.youtube.com

 

반응형

 

 

2023년 3월 8일  KBS 9시 뉴스 보도 자료

'전세 안전판' 전입신고, 확정일자, 모두 뚫렸다.

 

https://www.youtube.com/watch?v=2RHbvH0sR1Y 

 

반응형

Ceph storage를 사용하다가 Ceph cluster node 중 일부 Node를 강제로 재기동하다보면

아래와 같은 에러 로그를 Dashboard에서 보게 된다.

 

...

3/6/23 3:00:00 PM [WRN] overall HEALTH_WARN 1 mgr modules have recently crashed

3/6/23 2:50:00 PM [WRN] overall HEALTH_WARN 1 mgr modules have recently crashed

3/6/23 2:40:00 PM [WRN] overall HEALTH_WARN 1 mgr modules have recently crashed

...

 

위 로그가 출력되거나 Dashboard 화면에서 Unhealth warning 정보가 출력될 때,

아래처럼 `ceph crash archive-all` 명령을 수행하면 간단하게 해결된다.

 


$  kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash

##
## Ceph tool container 내부로 접속하여, ceph crash 목록을 확인
##

bash-4.4$ ceph crash ls

ID                                                                ENTITY  NEW
2023-02-01T07:02:56.432333Z_6ab1d847-9cbc-449b-9167-8b53e96774d8  mgr.a    *
2023-02-22T05:18:10.263896Z_7321ae9d-7dd8-49c9-a9e0-18ff892e3050  mgr.a    *

##
## ceph crash 상세 정보를 확인 (특이 사항이 있는지 확인하는 차원에서~)
##

bash-4.4$ ceph crash info 2023-02-22T05:18:10.263896Z_7321ae9d-7dd8-49c9-a9e0-18ff892e3050

{
    "backtrace": [
        "  File \"/usr/share/ceph/mgr/nfs/module.py\", line 154, in cluster_ls\n    return available_clusters(self)",
        ... 중간 생략 ...
        "orchestrator._interface.NoOrchestrator: No orchestrator configured (try `ceph orch set backend`)"
    ],
    "ceph_version": "17.2.5",
    "process_name": "ceph-mgr",
    ... 중간 생략 ...
    "utsname_version": "#66-Ubuntu SMP Fri Jan 20 14:29:49 UTC 2023"
}

##
## 아래 명령을 수행하여 crash 상태를 정리
## 

bash-4.4$ ceph crash archive-all

 

 

확인하는 차원에서 아래 명령으로 한번 더 ceph 상태를 확인한다.

 

bash-4.4$ ceph status
  cluster:
    id:     4e855f4b-085d-45d4-b713-19fc82d1a2a5
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum a,b,d (age 11d)
    mgr: b(active, since 11d), standbys: a
    osd: 3 osds: 3 up (since 11d), 3 in (since 4w)

  data:
    pools:   2 pools, 33 pgs
    objects: 3.69k objects, 13 GiB
    usage:   40 GiB used, 710 GiB / 750 GiB avail
    pgs:     33 active+clean

 


 

 

 

 

반응형

 

C language, Go(Golang), Netfilter, Netlink를 이용하여 Linux network을 제어하고 모니터링하는 방법을 알아보자~

 

 

개념 이해하기: Netfilter hooks into Linux networking packet flows

The following schematic shows packet flows through Linux networking:

 

From:&nbsp;&nbsp;https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks

 

 


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

 

 

 

위 문서를 읽고 나서, 아래 예제를 테스트하면서 이해하기.

$  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

 

Linux Networking From Go

Manipulating network interfaces, firewalling, and forwarding from Go.

tomdnetto.net

 

 

https://tomdnetto.net/post/advanced_nftables_with_go

 

Advanced NFTables With Go

NFTables like your mama taught you.

tomdnetto.net

 

 

 

반응형


 

작성일: 2024년 3월 2일

 

나는 가톨릭 신자이지만 인생이 가톨릭 신자 같지 않다.

일이 바쁘면 주일 미사를 빼먹고, 마음속으로는 이 사람 저 사람 욕을 많이 한다.

잘못한 사람을 용서하라는 Jesus 말씀은 Bible 읽을 때만 잠깐 생각나고, 나는 잘못한 사람을 응징하고 싶은 마음이 크다 ㅠㅠ

 

그런데 내 인생에서 굵직굵직한 이벤트는 모두 천주교(가톨릭)과 관련있다.

- 희안하게 서강대학교를 입학하려고 했던게 아닌데, 일이 이리저리 꼬이다보니 나는 어느새 서강대학교 학생이 되었다.

- 여자 친구도 천주교 신자였다. (현재 나의 아내 ^^)

- 결혼식을 성당에서 혼인 미사로 했다.

- 아들은 가톨릭대학교에 입학했다. (오늘이 가톨릭대학교 입학식)

- 그 외에도 등등...

그래서 하늘이 나에게 이렇게 살으라고 소명을 줬나보다 생각하면서 살고 있다.

 


서강대학교도 천주교 재단의 학교이지만, 내 기억에 입학미사라는 것은 없었고 다른 학교처럼 평범한 입학식 형식으로 치뤘다.

서강대학교 체육관에 옹기종기 모여서 조촐하게 입학생 선언하고 끝냈던 것으로 기억한다.

(서강대학교 입학식에 대한 30년 전 기억이 거의 없는 것으로 보아, 입학식이 아주 평범했던 것이 분명하다)

그런데 가톨릭대학교는 명동성당에서 입학식을 한다고 하여 나랑 아내랑 본업을 제끼고 아들의 입학식에 참석했다.

아~ 그러고보니 나랑 아내랑 혼인성사를 위한 '가나혼인강좌'도 이곳 명동성당에서 수강했었다.

20년 전, '가나혼인강좌' 수업 중에 70대 노부부가 직접 강단에 올라서서 소소한 인생 사는 얘기도 들려주었는데~~~

우리 가족이랑 명동 성당이랑 인연이 깊네 ^^

 

 

아이쿠~~ 이 많은 학생을 어쩔거야 !

 

대성당, 문화홀 등 이미 만석 상태라 입장을 못한 학생들이 밖에서 기다리고 있다.

 

대성당, 문화홀 등 미사를 할 수 있는 공간은 자리가 꽉 차서 입장 못하고, 밖에서 기다리는 학생이 적어도 500명은 되는 것 같다.

대학교 입학식에 이렇게 참여 인원이 많았던 적이 있었나?

 

저 뒤에 신부님이 다급하게 뛰어 나오면서 "아이쿠~ 이 많은 학생을 어쩔거야" 하는데, 예전 입학식에는 이렇게 많은 신입생이 오지 않았나 보다. 신부님도 처음 겪는 일인듯...

 

 

사진 출처: 가톨릭대학교 홈페이지

 

입학 미사가 끝나고 20분쯤 뒤, 가족들까지 와서 더욱 붐비는 명동성당

 

 

 

 

 

오늘 가톨릭대학교 입학식은 Ceremony를 진짜 제대로 한 것 같은 느낌. 
음식으로 비유하면, 한정식 Full course를 먹은 느낌 ^^

 

+ Recent posts