InetDaemon ¸¸µé±â
ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®



joinc´Â Firefox¿Í chrome¿¡¼­ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼­´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.
inetd µ¥¸ó Á¦ÀÛ

1절. ¼Ò°³

¿ì¸®´Â Áö³­¹ø¿¡ inetd ÇÁ·Î±×·¡¹Ö ¸¦ ÅëÇÏ¿³ inetd µ¥¸óÀÇ ÀÛµ¿¹æ½Ä°ú inetd ¸¦ ÀÌ¿ëÇÑ ¼­¹öÇÁ·Î±×·¡¹Ö ¹æ¹ý¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸¾Ò´Ù.

À̹ø ±â»ç´Â inetd µ¥¸ó°ú ºñ½ÁÇÑ ÇÁ·Î±×·¥À» Á÷Á¢ ±¸ÇöÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ¼­ ¼Ò°³Çϰí ÀÖ´Ù.


2절. my_inetd Á¦ÀÛ

À̹ø¿¡ ¸¸µé ÇÁ·Î±×·¥ÀÇ À̸§Àº my_inetd ¶ó°í ¸í¸íÇϵµ·Ï ÇÒ°ÍÀÌ´Ù. ½î¾²ÆÄÀÏÀÇ À̸§Àº my_inetd.cpp °¡ µÉ°ÍÀÌ´Ù.


2.1절. ÀÛµ¿ ÇÁ·Î¼¼½º

my_inetd ÀÇ ÀÛµ¿ ÇÁ·Î¼¼½º´Â ±âº»ÀûÀ¸·Î inetd ¿Í °°Àº ¹æ½ÄÀ» ÃëÇÏ°Ô µÉ°ÍÀÌ´Ù.

Áï ¼³Á¤ÆÄÀÏÀ» Àо, ÇØ´ç Æ÷Æ®¿¡¼­ accept ´ë±â¸¦ ÇÏ´Ù°¡ Æ÷Æ®¿¡ ¿¬°áÀÌ µé¾î¿À¸é, Æ÷Æ®¿¡ ¿¬°áµÈ ÇÁ·Î±×·¥À» fork&exec ¹æ½ÄÀ¸·Î ½ÇÇà½ÃŰ°Ô µÉ°ÍÀÌ´Ù. fork Çϸ鼭 accept ½Ã ¸¸µé¾îÁø ¼ÒÄÏÀ» stdin(0) À¸·Î º¹»ç(dup2) ÇÏ°Ô µÈ´Ù. ±×·¯¹Ç·Î ÀÚ½Ä ÇÁ·Î¼¼½º´Â stdin(0) À» ÀÌ¿ëÇØ¼­ Ŭ¶óÀÌ¾ðÆ®¿Í Åë½ÅÀ» ÇÒ¼ö ÀÖ°Ô µÈ´Ù.


my_inetd ´Â ½ÃÀÛÇÏ¸é ¿ì¼± ¼³Á¤ÆÄÀÏÀ» ÀоîµéÀ̴µ¥, ¼³Á¤ÆÄÀÏÀÇ ³»¿ëÀº ´ÙÀ½°ú °°Àº Æ÷¸äÀ» °¡Áø´Ù.
4444,/usr/local/bin/zipcode
5555,/usr/local/bin/zipcode2
			
°¢ Çʵå´Â ',' ·Î ±¸ºÐµÇ¸ç ù¹øÂ° Çʵå´Â port ¹øÈ£, 2¹øÂ° Çʵå´Â port ·Î ¿¬°áÀÌ µé¾î¿ÔÀ»¶§ ½ÇÇà½Ãų ¼­¹öÇÁ·Î±×·¥ÀÇ À̸§ÀÌ µÈ´Ù.

ÀÏ´Ü ¼³Á¤ÆÄÀÏÀ» ÅëÇØ¼­ ÀоîµéÀÎ port ÀÇ ¼ö¸¸Å­ socket ¸¦ ¸¸µé¾î ÁØ´Ù. ±×ÈÄ °¢ socket ÁöÁ¤¹øÈ£¿¡ ´ëÇÑ ¿¬°áÀ» ±â´Ù¸®°Ô µÈ´Ù. À̶§ °¢ ¼ÒÄÏ ÁöÁ¤¹øÈ£ÀÇ accept ¿¡¼­ block µÇ¸é ¾ÈµÇ¹Ç·Î polling À» ÀÌ¿ëÇØ¼­ accept À̺¥Æ®¸¦ °Ë»çÇϵµ·Ï ÇÑ´Ù.

ƯÁ¤ ¼ÒÄÏ ÁöÁ¤¹øÈ£¿¡ ¿¬°áÀÌ µé¾î¿À¸é fork ½ÃŲÈÄ port ¿¡ ÁöÁ¤µÈ ¼­¹öÇÁ·Î±×·¥À» exec ½ÇÇà½ÃŲ´Ù. exec ½ÇÇàÇϱâ Àü¿¡, ¼­¹öÇÁ·Î±×·¥¿¡ Ŭ¶óÀÌ¾ðÆ®¿Í Åë½ÅÇÒ ¼ÒÄÏ ÁöÁ¤¹øÈ£¸¦ Àü´Þ ½ÃÄÑÁà¾ß ÇϹǷΠdup2 ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ¼ÒÄÏÁöÁ¤¹øÈ£¸¦ 0¹øÀ¸·Î º¹»çÇϵµ·Ï ÇÑ´Ù. º¹»çÇÑÈÄ ±âÁ¸ÀÇ ¼ÒÄÏÁöÁ¤¹øÈ£´Â close ½Ã۵µ·Ï ÇÑ´Ù.


2.2절. ÀڷᱸÁ¶

¼ÒÄÏÁöÁ¤¹øÈ£¿Í poll ±×¸®°í port ¿¡ ´ëÇÑ ½ÇÇ༭¹ö À̸§À» ÀúÀåÇÏ°Ô µÇ´Â ÀڷᱸÁ¶¿Í ¿¬°ü°ü°è´Â ¾Æ·¡¿Í °°´Ù.

sockfd ´Â ¼ÒÄÏÁöÁ¤¹øÈ£°¡ ÀúÀåµÇ´Â ´Ü¼øÇÑ ¹è¿­ÀÌ´Ù. ¼³Á¤ÆÄÀÏ¿¡ ÀÖ´Â ¼­ºñ½º ¸®½ºÆ®ÀÇ Å©±â¿Í µ¿ÀÏÇÑ Å©±â¸¦ °¡Áö°Ô µÉ°ÍÀÌ´Ù. poll Àº ¼ÒÄÏÁöÁ¤¹øÈ£¿¡ ´ëÇÑ polling °Ë»ç¸¦ ÇÏ°ÔµÉ poll ±¸Á¶Ã¼ÀÇ ÀÏ¹Ý ¹è¿­ ÀÌ´Ù. ¸¶Áö¸· vector<struct s_info> ´Â s_info ±¸Á¶Ã¼¸¦ vector È­ ½ÃŲ °ÍÀÌ´Ù. s_info ±¸Á¶Ã¼¿¡´Â ÇØ´ç Æ÷Æ®¹øÈ£¿¡ ´ëÇØ¼­ ½ÇÇàÇØ¾ßÇÒ ÇÁ·Î±×·¥¿¡ °üÇÑ Á¤º¸°¡ µé¾îÀÖ´Ù.

3°³ÀÇ ÀڷᱸÁ¶µéÀº ÷ÀÚ¹øÈ£·Î ¼­·Î¸¦ ÂüÁ¶ÇÒ¼ö ÀÖ´Ù. Áï sockfd 4 ¿¡ ´ëÇÑ ¿¬°á event(POLLIN) ´Â poll 0 À» ÀÌ¿ëÇØ¼­ °Ë»çÇÒ¼ö ÀÖÀ¸¸ç, ¿¬°á event°¡ ¹ß»ýÇß´Ù¸é, vector<struct s_info> ÀÇ 0¹ø ¿ø¼Ò¸¦ ÂüÁ¶Çؼ­ ¾î¶² ÇÁ·Î±×·¥À» ½ÇÇà½ÃÄÑ¾ß ÇÏ´ÂÁö(proc) °áÁ¤ÇÒ¼ö ÀÖ°Ô µÈ´Ù.

À§¿¡¼­´Â ÀڷᱸÁ¶¸¦ vector ·Î »ç¿ëÇßÁö¸¸ ¹è¿­À» »ç¿ëÇØµµ ÀüÇô ¹®Á¦ ¾øÀ» °ÍÀÌ´Ù.


2.3절. ÄÚµù

À§ÀÇ ÇÁ·Î¼¼½º¸¦ º¸¸é ¾Ë°ÙÁö¸¸, my_inetd ¸¦ ¸¸µé±â À§Çؼ­ ¾î¶² Ưº°ÇÑ ±â¼úÀ» ÇÊ¿ä·Î ÇÏ´Â°Ç ¾Æ´Ï´Ù. ±âÁ¸ÀÇ ¾Ë°í ÀÖ´Â Áö½ÄÀ» ÀÌ¿ëÇÑ ±¸ÇöÀÌ´Ù. ±×·¯¹Ç·Î ¾Æ·¡ÀÇ ¿¹Á¦ ÇÁ·Î±×·¥À» ÀÌÇØÇϴµ¥ º° ¾î·Á¿òÀº ¾øÀ»°ÍÀÌ´Ù.

ÇÁ·Î±×·¡¹Ö ¾ð¾î·Î C++À» »ç¿ëÇÏ¿´´Ù. ÀÌÀ¯´Â vector¿Í string ¸¦ »ç¿ëÇϱâ À§ÇÔÀÌ´Ù. string ¸¦ »ç¿ëÇÑ ÀÌÀ¯´Â, ¹®ÀÚ¿­À» Á»´õ ½±°Ô »ç¿ëÇϱâ À§ÇÔÀ̸ç, vector ¸¦ »ç¿ëÇÑ ÀÌÀ¯´Â ¼³Á¤ÆÄÀÏ¿¡¼­ ÀоîµéÀÎ ³»¿ëÀ» ÀúÀåÇϱâ À§ÇÑ ÀڷᱸÁ¶¸¦ Á»´õ ½±°Ô ±¸ÇöÇϱâ À§Çؼ­ÀÌ´Ù. ´Ù¸¥ ¹æ¹ýÀ¸·Î ±¸ÇöÇØµµ ¹°·Ð »ó°üÀº ¾ø´Ù. ÇÊÀÚÀÇ °æ¿ì ÄÚµù½Ã°£À» ´ÜÃà½Ã۱â À§Çؼ­ vector¿Í string ¸¦ »ç¿ëÇßÀ» »ÓÀÌ´Ù. ±×·¸Áö¸¸ string ¿Í vector À» »ç¿ëÇÑ ¿Ü¿¡´Â C ½ºÅ¸ÀÏÀÇ ÄÚµù±â¹ýÀ» µû¸£°í ÀÖ´Ù.

¿¹Á¦: my_inetd.cpp

#include <string>
#include <vector>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/poll.h>
struct s_info
{
    int    port;
    string proc;
};
int main(int argc, char **argv)
{
    FILE *fp;
    char buf[80];
    char port[6];
    char exec_proc[80];
    char comma[1];
    int    *sockfd;
    int state;
    socklen_t clilen;
    int pid;

    struct sockaddr_in clientaddr, serveraddr; 
    struct pollfd *client;
    struct s_info service_info;

    int  i; 
    vector<struct s_info> info_list;

    // ¼³Á¤ÆÄÀÏÀ» Àоîµé¿©¼­ info_list ÀڷᱸÁ¶¿¡ 
    // push ÇÑ´Ù.  
    fp = fopen("my_inetd.cfg", "r");
    while(fgets(buf, 80, fp) != NULL)
    {
        printf("%s", buf);
        sscanf(buf, "%[0-9]%[,]%s", port,comma,exec_proc);
        service_info.port = atoi(port); 
        service_info.proc = exec_proc;
        info_list.push_back(service_info);
    }

    // ¼³Á¤ÆÄÀÏÀÇ ³»¿ëÀ» Åä´ë·Î sockfd ÀÇ Å©±â¿Í 
    // polling ¿¡ »ç¿ëµÉ client poll ±¸Á¶Ã¼ÀÇ Å©±â¸¦ °áÁ¤ÇÑ´Ù. 
    sockfd = (int *)malloc(info_list.size());
    client = (struct pollfd *)malloc(info_list.size());

    // ¼³Á¤ÆÄÀÏ¿¡ ¼³Á¤µÈ port ¸¸Å­ socket ¸¦ ¸¸µç´Ù. 
    for (i = 0; i < info_list.size(); i++)
    {
        if ((sockfd[i] = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
        {
            perror("socket error : ");
            exit(0);
        }
        bzero(&serveraddr, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
        serveraddr.sin_port = htons(info_list[i].port);
        state = bind(sockfd[i], (struct sockaddr *)&serveraddr, 
                     sizeof(serveraddr));

        if (state == -1)
        {
            perror("bind error : ");
            exit(0);
        }
        state = listen(sockfd[i], 5);
        if (state == -1)
        {
            perror("bind error : ");
            exit(0);
        }

        // ¸¸µé¾îÁø socket ÁöÁ¤¹øÈ£´Â polling À» À§Çؼ­ 
        // poll ±¸Á¶Ã¼¿¡ ÀÔ·ÂÇÑ´Ù. 
        client[i].fd = sockfd[i]; 
        client[i].events = POLLIN;

    }
    clilen = sizeof(clientaddr);
    for(;;)
    {
        int nread;
        int client_sockfd;

        // ¸¸µé¾îÁø socket ¿¡ ´ëÇØ¼­ Æú¸µÇÑ´Ù. 
        // ¸¸¾à client poll ±¸Á¶Ã¼¿¡ ÀбⰡ ¹ß»ýÇϸé(POLLIN) 
        // block ÀÌ ÇØÁ¦ µÇ°í ´ÙÀ½ ÄÚµå·Î ³Ñ¾î°£´Ù. 
        nread = poll(client, info_list.size(),-1);
        for (i = 0; i < info_list.size(); i++)
        {
            // ¾î¶² client ¸â¹ö¿¡¼­ POLLINÀÌ ¹ß»ýÇß´ÂÁö °Ë»çÇÑÈÄ 
            // fork ½ÃŰ°í ³ª¼­ ÇØ´ç port ¿¡ ´ëÇØ ½ÇÇà½ÃŰ·Á°í ¼³Á¤ÇصР
            // ¼­¹ö ÇÁ·Î±×·¥À» exec ½ÇÇà½ÃŲ´Ù. 
            client[i].fd = sockfd[i]; 
            client[i].events = POLLIN;
            if (client[i].revents & POLLIN) 
            {
                client_sockfd = accept(client[i].fd, 
                        (struct sockaddr *)&clientaddr, 
                        &clilen);
                if (client_sockfd > 0)
                {
                    pid = fork();
                    if (pid == 0)
                    {
                        // exec ½ÇÇà½Ã۱â Àü¿¡ client_sockfd ¸¦ dup2 ¸¦ ÀÌ¿ë Ç¥ÁØÀÔ·ÂÀ¸·Î 
                        // º¹»çÇÑ´Ù. 
                        dup2(client_sockfd, 0);
                        execl(info_list[i].proc.c_str(),
                              info_list[i].proc.substr(info_list[i].proc.rfind("/")+1).c_str(), 0);
                    }
                }
                // ¿­¸° ¼ÒÄÏÀÌ ºÎ¸ð ÇÁ·Î¼¼½º¿¡¼­´Â ÇÊ¿ä ¾øÀ½À¸·Î 
                // close ÇÑ´Ù. 
                close(client_sockfd);
            }
        }
    }
}

ÄÚµå´Â ÀüüÀûÀ¸·Î Á¤¸®µÇÁö ¾ÊÀº ¸ð½ÀÀ» º¸¿©ÁØ´Ù. ÀÌÀ¯´Â ¾îµð±îÁö³ª "ÀÌ·¸°Ô ±¸ÇöÀÌ °¡´ÉÇÏ´Ù" ¶ó´Â°É º¸¿©ÁÖ±â À§Çؼ­ Äڵ尡 ¸¸µé¾îÁ³±â ¶§¹®ÀÌ´Ù. ºÎÁ·ÇÑ ±â´ÉÀ» º¸ÃæÇϴ°Ͱú, ÄÚµå ÃÖÀûÈ­¹× ¿¡·¯Ã³¸®´Â °¢ÀÚÀÇ ¸òÀ¸·Î ³²°Ü ³õµµ·Ï ÇϰڴÙ.


2.4절. Å×½ºÆ®

¿ì¼± inetd ¹æ½ÄÀÇ ¼­¹öÇÁ·Î±×·¥À» ÁغñÇØ¾ß ÇÑ´Ù. À̰ÍÀº inetd ÇÁ·Î±×·¡¹Ö¿¡ ÀÖ´Â zipcode_inetd.c ¸¦ ±×´ë·Î ÀÌ¿ë Çϵµ·Ï ÇÑ´Ù. À̰ÍÀ» /usr/local/bin/zipcode ·Î º¹»çÇϵµ·ÏÇÏÀÚ. ±×´ÙÀ½ my_inetd ¸¦ ½ÇÇà½ÃŰ°í ¼ÀÇ÷Π¾Ë¾Æº¸´Â ¼ÒÄÏÇÁ·Î±×·¡¹Ö(1)ÀÇ zipcode_cli.c ¸¦ ÀÌ¿ëÇØ¼­ Å×½ºÆ® ÇÏ¸é µÈ´Ù.

[root@localhost test]# cp zipcode_inetd /usr/local/bin/zipcode 
[root@localhost test]# ./my_inetd 
...
[root@localhost test]# ./zipcode_cli 4444
Áö¿ªÀ̸§ ÀÔ·Â : ¼­¿ï
¼­¿ï½Ã °­³²±¸ ¿ª»ïµ¿:100-500
¼­¿ï½Ã °­³²±¸ »ï¼ºµ¿:108-508
¼­¿ï½Ã ¼ÛÆÄ±¸ µ¿Çص¿:212-789
¼­¿ï½Ã °­ºÏ±¸ ÀÎõµ¿:911-200
...
			

º¸Åë telnet ¼­ºñ½º´Â 23¹ø Æ÷Æ®·Î ÀÌ·ç¾îÁö¸ç ÅÚ³Ý ¼­ºñ½º ¿äûÀÌ ÀÖÀ»°æ¿ì inetd °¡ /usr/sbin/in.telnetd ¸¦ fork&exec ·Î ½ÇÇà½ÃŲ´Ù. ÀÌÁ¦ ¿ì¸®°¡ ¸¸µç my_inetd °¡ °ú¿¬ telnet ¼­ºñ½ºµµ °¡´ÉÇÑÁö¸¦ Å×½ºÆ® ÇØº¸µµ·Ï ÇÏÀÚ. Å×½ºÆ® Àü¿¡ ±âÁ¸¿¡ ¶°ÀÖ´Â telnet ¼­ºñ½º¸¦ disable »óÅ·Π¸¸µéµµ·Ï ÇÏÀÚ. xinetd ¹æ½ÄÀ̶ó¸é /etc/xinetd.d ¹Ø¿¡ ÀÖ´Â telnet ÆÄÀÏÀ» ¿­¾î¼­ "disable = yes" ·Î ¹Ù²Ù¸é µÉ°ÍÀÌ´Ù. ¸¸¾à inetd ¹æ½ÄÀ̶ó¸é /etc/inetd.conf ÆÄÀÏÀ» ¿­¾î¼­ "telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd" ºÎºÐÀ» ÁÖ¼®Ã³¸® ÇÏ¸é µÈ´Ù. ÁÖ¼® ó¸®ÈÄ xinetd ¿Í inetd µ¥¸óÀ» Àç ½ÇÇà ½Ã۵µ·Ï ÇÑ´Ù.

[root@localhost test]# ps -ax | grep xinetd
4616 ?        S      0:00 xinetd -stayalive -reuse -pidfile /var/run/xinetd.pid
[root@localhost test]# kill -HUP 4616 

ÀÌÁ¦ telnet ¼­ºñ½º°¡ disable »óÅ·ΠµÇ¾î ÀÖÀ»°ÍÀÌ´Ù. Á¤¸»·Î disable »óŰ¡ µÇ¾îÀÖ´ÂÁö È®ÀÎÀ» ¿øÇÑ´Ù¸é nmap °ú °°Àº Æ÷Æ®½ºÄ³³Ê µµ±¸¸¦ »ç¿ëÇÏ¸é µÈ´Ù.

[root@localhost xinetd.d]# !nmap
nmap 127.0.0.1

Starting nmap V. 2.54BETA22 ( www.insecure.org/nmap/ )
Interesting ports on localhost (127.0.0.1):
(The 1538 ports scanned but not shown below are in state: closed)
Port       State       Service
7/tcp      open        echo                    
22/tcp     open        ssh                     
110/tcp    open        pop-3                   
			
À§´Â ÇÊÀÚÀÇ ÄÄÇ»Å͸¦ ½ºÄ³³Ê ÇѰǵ¥, telnet ¼­ºñ½º°¡ µÇ°í ÀÖÁö ¾ÊÀ½À» ¾Ë¼ö ÀÖ´Ù.

ÀÌÁ¦ my_inetd.cfg ¿¡ ´ÙÀ½°ú °°Àº ³»¿ëÀ» Ãß°¡½Ã۵µ·Ï ÇÏÀÚ.

23,/usr/sbin/in.telnetd
±×´ÙÀ½ my_inetd ÇÁ·Î±×·¥À» ´Ù½Ã ½ÇÇà½ÃŲÈÄ telnet ¿¬°áÀ» ÇØº¸µµ·Ï ÇÏÀÚ.
	
[root@localhost test]# ./inetd 
4444,/usr/local/bin/zipcode
5555,/usr/local/bin/zipcode2
23,/usr/sbin/in.telnetd
...
[root@localhost test]# telnet 127.0.0.1 
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

HancomLinux release 2.2
Kernel 2.4.13-1hl on an i686
login: 
¸Å¿ì ³î¶ø°Ôµµ telnet ¼­ºñ½º°¡ Á¦´ë·Î µÊÀ» ¾Ë¼ö ÀÖ´Ù(Á¤¸» ³î¶ø´Ù).

±×·¯³ª À§ÀÇ my_inetd ÇÁ·Î±×·¥ÀÌ ¸ðµç ¼­ºñ½º (smtp, pop3)¿Í °°Àº ¼­ºñ½º¸¦ ½ÇÇà½Ãų¼ö´Â ¾øÀ»°ÍÀÌ´Ù. telnet °°Àº °æ¿ì¿¡´Â ¾Æ±Ô¸ÕÆ®°¡ ¾øÀÌ ½ÇÇàµÇ¹Ç·Î my_inetd.c ÀÇ ÄÚµå·Î ¹®Á¦¾øÀÌ exec ½Ãų¼ö ÀÖÀ¸³ª, pop3, smtp °°Àº °æ¿ì¿¡´Â ¾Æ±Ô¸ÕÆ®¸¦ ÇÊ¿ä·Î Çϴ°æ¿ì°¡ ÀÖ´Ù. ±×·±µ¥ ¿ì¸®ÀÇ ÄÚµå´Â ÀÌ·¯ÇÑ °Í±îÁö Áö¿øÇÏÁö´Â ¾Ê´Â´Ù. À̰ÍÀº ¾à°£¸¸ ¼öÁ¤Çϸé Áö¿øÇϵµ·Ï ÇÒ¼ö ÀÖÀ¸´Ï ½Ã°£ÀÌ ³²À¸¸é ¼öÁ¤ÇØ º¸µµ·Ï ÇÏÀÚ.

category_network
programing
category__5
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.