기본적으로 윈도우 서버가 아닌 일반 사용자 윈도우는 다중 원격데스크탑 연결이 안된다. 이는 마이크로소프트에서 사전에 막아두었기 때문이다. termsrv.dll 라는 파일이 있는데 이 파일을 수정하면 다중 데스크탑 연결을 할 수 있다.

기본적으로 윈도우 서버가 아닌 일반 사용자 윈도우는 다중 원격데스크탑 연결이 안된다. 이는 마이크로소프트에서 사전에 막아두었기 때문이다. termsrv.dll 라는 파일이 있는데 이 파일을 수정하면 다중 데스크탑 연결을 할 수 있다.


영가시여 저희들이 일심으로 염불하니
무명업장
소멸하고 반야지혜 드러내어
생사고해 벗어나서 해탈열반 성취하사
극락왕생 하옵시고 모두성불 하옵소서
사대육신 허망하여 결국에는 사라지니
이육신에 집착말고 참된도리 깨달으면
모든고통 벗어나고 부처님을 친견하리
살아생전 애착하던 사대육신 무엇인고
한순간에 숨거두니 주인없는 목석일세
인연따라 모인것은 인연따라 흩어지니
태어남도 인연이요
돌아감도 인연인걸
그무엇을 애착하고 그무엇을 슬퍼하랴
몸둥이를 가진자는 그림자가 따르듯이
일생동안
살다보면 죄없다고 말못하리
죄의실체 본래없어 마음따라 생기나니
마음씀이 없어질때 죄업역시 사라지네
죄란생각 없어지고 마음또한 텅비어서
무념처에 도달하면 참회했다 말하리라
한마음이 청정하면 온세계가
청정하니
모든업장 참회하여 청정으로 돌아가면
영가님이 가시는길 광명으로 가득하리
가시는길 천리만리
극락정토 어디인가
번뇌망상 없어진곳 그자리가 극락이니
삼독심을 버리고서 부처님께 귀의하면
무명업장 벗어나서 극락세계 왕생하리
제행은 무상이요 생자는 필멸이라
태어났다
죽는것은 모든생명 이치이니
임금으로 태어나서 온천하를 호령해도
결국에는 죽는것을 영가님은 모르는가
영가시여 어디에서 이세상에 오셨다가
가신다니 가시는곳 어디인줄 아시는가
태어났다 죽는것은 중생계의
흐름이라
이곳에서 가시면은 저세상에 태어나니
오는듯이 가시옵고 가는듯이 오신다면
이육신의 마지막을
걱정할것 없잖은가
일가친척 많이있고 부귀영화 높았어도
죽는길엔 누구하나 힘이되지 못한다네
맺고쌓은
모든감정 가시는길 짐되오니
염불하는 인연으로 남김없이 놓으소서
미웠던일 용서하고 탐욕심을 버려야만
청정하신 마음으로 불국정토 가시리라
삿된마음 멀리하고 미혹함을 벗어나야
반야지혜 이루시고 왕생극락
하오리다
본마음은 고요하여 예와지금 없다하니
태어남은 무엇이고 돌아감은 무엇인가
부처님이 관밖으로 양쪽발을 보이셨고
달마대사 총령으로
짚신한짝 갖고갔네
이와같은 높은도리 영가님이 깨달으면
생과사를 넘었거늘 그무엇을 슬퍼하랴
뜬구름이
모였다가 흩어짐이 인연이듯
중생들의 생과사도 인연따라 나타나니
좋은인연 간직하고 나쁜인연 버리시면
이다음에 태어날때 좋은인연 만나리라
사대육신 흩어지고 업식만을 가져가니
탐욕심을 버리시고 미움또한
거두시며
사견마저 버리시어 청정해진 마음으로
부처님의 품에안겨 왕생극락 하옵소서
돌고도는 생사윤회
자기업을 따르오니
오고감을 슬퍼말고 환희로써 발심하여
무명업장 밝히시면 무거운짐 모두벗고
삼악도를
뛰어넘어 극락세계 가오리다
이세상에 처음올때 영가님은 누구셨고
사바일생 마치시고 가시는이 누구신가
물이얼어 얼음되고 얼음녹아 물이되듯
이세상의 삶과죽음 물과얼음 같으오니
육친으로 맺은정을 가벼웁게
거두시고
청정해진 업식으로 극락왕생 하옵소서
영가시여 사바일생 다마치는 임종시에
지은죄업 남김없이
부처님께 참회하고
한순간도 잊지않고 부처님을 생각하면
가고오는 곳곳마다 그대로가 극락이니
첩첩쌓인
푸른산은 부처님의 도량이요
맑은하늘 흰구름은 부처님의 발자취며
뭇생명의 노래소리 부처님의 설법이고
대자연의 고요함은 부처님의 마음이니
불심으로 바라보면 온세상이 불국토요
범부들의 마음에는 불국토가
사바로다
애착하던 사바일생 하룻밤의 꿈과같고
나다너다 모든분별 본래부터 공이거니
빈손으로 오셨다가
빈손으로 가시거늘
그무엇에 얽매여서 극락왕생 못하시나
저희들이 일심으로 독송하는 진언따라
지옥세계 무너지고 맺은원결 풀어지며
아미타불 극락세계 상품상생 하옵소서
게임 루프는 모든 게임의 심장과 같은 역활을 합니다. 이 게임 루프 없이는 어떠한 게임이라도 실행될 수 없습니다. 이렇게 게임루프가 중요한 반면에 불행히도 이러한 내용을 다루는 사설을 인터넷에서 찾기 힘듭니다. 따라서 이번 글에서는 이 게임 루프에 대해 중심적으로 언급하고 설명할 것입니다.
모든 게임은 사용자입력을 받고, 그에 대한 상태를 업데이트하고, 인공지능을 조작하고, 음악이나 소리 효과를 반영하고 최종적으로 화면에 표시되게 됩니다. 이 모든 것들은 게임루프를 통해서 연달아 일어나게 됩니다.
아래의 것은 가장 기초적인 게임 루프의 예제 입니다.
bool game_is_running = true;
while( game_is_running ) {
update_game();
display_game();
}
The problem with this simple loop is that it doesn't handle time, the game just runs. On slower hardware the game runs slower, and on faster hardware faster. Back in the old days when the speed of the hardware was known, this wasn't a problem, but nowadays there are so many hardware platforms out there, that we have to implement some sort of time handling. There are many ways to do this, and I'll discuss them in the following sections.
First, let me explain 2 terms that are used throughout this article:
An easy solution to the timing issue is to just let the game run on a steady 25 frames per second. The code then looks like this:
const int FRAMES_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;
DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started
int sleep_time = 0;
bool game_is_running = true;
while( game_is_running ) {
update_game();
display_game();
next_game_tick += SKIP_TICKS;
sleep_time = next_game_tick - GetTickCount();
if( sleep_time >= 0 ) {
Sleep( sleep_time );
}
else {
// Shit, we are running behind!
}
}
This is a solution with one huge
benefit: it's simple! Since you know that update_game() gets called 25
times per second, writing your game code is quite straight forward.
For example, implementing a replay function in this kind of game
loop is easy. If no random values are used in the
game, you can just log the input changes of the user
and replay them later.
On your testing hardware you can adapt the FRAMES_PER_SECOND to an ideal value, but what will happen on faster or slower hardware? Well, let's find out.
If the hardware can handle the defined FPS, no problem. But the problems will start when the hardware can't handle it. The game will run slower. In the worst case the game has some heavy chunks where the game will run really slow, and some chunks where it runs normal. The timing becomes variable which can make your game unplayable.
The game will have no problems on fast hardware, but you are wasting so many precious clock cycles. Running a game on 25 or 30 FPS when it could easily do 300 FPS... shame on you! You will lose a lot of visual appeal with this, especially with fast moving objects.
On the other hand, with mobile devices, this can be seen as a benefit. Not letting the game constantly run at it's edge could save some battery time.
Making the FPS dependent on a constant game speed is a solution that is quickly implemented and keeps the game code simple. But there are some problems: Defining a high FPS will pose problems on slower hardware, and defining a low FPS will waste visual appeal on fast hardware.
Another implementation of a game loop is to let it run as fast as possible, and let the FPS dictate the game speed. The game is updated with the time difference of the previous frame.
DWORD prev_frame_tick;
DWORD curr_frame_tick = GetTickCount();
bool game_is_running = true;
while( game_is_running ) {
prev_frame_tick = curr_frame_tick;
curr_frame_tick = GetTickCount();
update_game( curr_frame_tick - prev_frame_tick );
display_game();
}
The game code becomes
a bit more complicated because we now have to consider the
time difference in the update_game() function. But still, it's not that
hard.
At first sight this looks like the ideal solution to our problem. I have seen many smart programmers implement this kind of game loop. Some of them probably wished they would have read this article before they implemented their loop. I will show you in a minute that this loop can have serious problems on both slow and fast (yes, FAST!) hardware.
Slow hardware can sometimes cause certain delays at some points, where the game gets "heavy". This can definitely occur with a 3D game, where at a certain time too many polygons get shown. This drop in frame rate will affect the input response time, and therefore also the player's reaction time. The updating of the game will also feel the delay and the game state will be updated in big time-chunks. As a result the reaction time of the player, and also that of the AI, will slow down and can make a simple maneuver fail, or even impossible. For example, an obstacle that could be avoided with a normal FPS, can become impossible to avoid with a slow FPS. A more serious problem with slow hardware is that when using physics, your simulation can even explode!
You are probably wondering how the above game loop can go wrong on fast hardware. Unfortunately, it can, and to show you, let me first explain something about math on a computer.
The memory space of a float or double value is limited, so some values cannot be represented. For example, 0.1 cannot be represented binary, and therefore is rounded when stored in a double. Let me show you using python:
>>> 0.1 0.10000000000000001This itself is not dramatic, but the consequences are. Let's say you have a race-car that has a speed of 0.001 units per millisecond. After 10 seconds your race-car will have traveled a distance of 10.0. If you split this calculation up like a game would do, you have the following function using frames per second as input:
>>> def get_distance( fps ): ... skip_ticks = 1000 / fps ... total_ticks = 0 ... distance = 0.0 ... speed_per_tick = 0.001 ... while total_ticks < 10000: ... distance += speed_per_tick * skip_ticks ... total_ticks += skip_ticks ... return distanceNow we can calculate the distance at 40 frames per second:
>>> get_distance( 40 ) 10.000000000000075Wait a minute... this is not 10.0??? What happened? Well, because we split up the calculation in 400 additions, a rounding error got big. I wonder what will happen at 100 frames per second...
>>> get_distance( 100 ) 9.9999999999998312What??? The error is even bigger!! Well, because we have more additions at 100 fps, the rounding error has more chance to get big. So the game will differ when running at 40 or 100 frames per second:
>>> get_distance( 40 ) - get_distance( 100 ) 2.4336088699783431e-13You might think that this difference is too small to be seen in the game itself. But the real problem will start when you use this incorrect value to do some more calculations. This way a small error can become big, and fuck up your game at high frame rates. Chances of that happening? Big enough to consider it! I have seen a game that used this kind of game loop, and which indeed gave trouble at high frame rates. After the programmer found out that the problem was hiding in the core of the game, only a lot of code rewriting could fix it.
This kind of game loop may seem very good at first sight, but don't be fooled. Both slow and fast hardware can cause serious problems for your game. And besides, the implementation of the game update function is harder than when you use a fixed frame rate, so why use it?
Our first solution, FPS dependent on Constant Game Speed, has a problem when running on slow hardware. Both the game speed and the framerate will drop in that case. A possible solution for this could be to keep updating the game at that rate, but reduce the rendering framerate. This can be done using following game loop:
const int TICKS_PER_SECOND = 50;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 10;
DWORD next_game_tick = GetTickCount();
int loops;
bool game_is_running = true;
while( game_is_running ) {
loops = 0;
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
update_game();
next_game_tick += SKIP_TICKS;
loops++;
}
display_game();
}
The game will be updated at a steady 50 times per second, and rendering is done as fast as possible. Remark that when rendering is done more than 50 times per second, some subsequent frames will be the same, so actual visual frames will be dispayed at a maximum of 50 frames per second. When running on slow hardware, the framerate can drop until the game update loop will reach MAX_FRAMESKIP. In practice this means that when our render FPS drops below 5 (= FRAMES_PER_SECOND / MAX_FRAMESKIP), the actual game will slow down.
On slow hardware the frames per second will drop, but the game itself will hopefully run at the normal speed. If the hardware still can't handle this, the game itself will run slower and the framerate will not be smooth at all.
The game will have no problems on fast hardware, but like the first solution, you are wasting so many precious clock cycles that can be used for a higher framerate. Finding the balance between a fast update rate and being able to run on slow hardware is crucial.
Using a constant game speed with a maximum FPS is a solution that is easy to implement and keeps the game code simple. But there are still some problems: Defining a high FPS can still pose problems on slow hardware (but not as severe as the first solution), and defining a low FPS will waste visual appeal on fast hardware.
Would it be possible to improve the above solution even further to run faster on slow hardware, and be visually more atractive on faster hardware? Well, lucky for us, this is possible. The game state itself doesn't need to be updated 60 times per second. Player input, AI and the updating of the game state have enough with 25 frames per second. So let's try to call the update_game() 25 times per second, no more, no less. The rendering, on the other hand, needs to be as fast as the hardware can handle. But a slow frame rate shouldn't interfere with the updating of the game. The way to achieve this is by using the following game loop:
const int TICKS_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 5;
DWORD next_game_tick = GetTickCount();
int loops;
float interpolation;
bool game_is_running = true;
while( game_is_running ) {
loops = 0;
while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) {
update_game();
next_game_tick += SKIP_TICKS;
loops++;
}
interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick )
/ float( SKIP_TICKS );
display_game( interpolation );
}
With this kind of game loop, the implementation of update_game()
will stay easy. But unfortunately, the display_game() function gets more complex.
You will have to implement a prediction function that takes the
interpolation as argument. But don't worry, this isn't hard, it just
takes a bit more work. I'll explain below how this interpolation
and prediction works, but first let me show you why it
is needed.
The gamestate gets updated 25 times per second, so if you don't use interpolation in your rendering, frames will also be displayed at this speed. Remark that 25 fps isn't as slow as some people think, movies for example run at 24 frames per second. So 25 fps should be enough for a visually pleasing experience, but for fast moving objects, we can still see a improvement when doing more FPS. So what we can do is make fast movements more smooth in between the frames. And this is where interpolation and a prediction function can provide a solution.
Like I said the game code runs on it's own frames per second, so when you draw/render your frames, it is possible that it's in between 2 gameticks. Let's say you have just updated your gamestate for the 10Th time, and now you are going to render the scene. This render will be in between the 10Th and 11Th game update. So it is possible that the render is at about 10.3. The 'interpolation' value then holds 0.3. Take this example: I have a car that moves every game tick like this:
position = position + speed;
If in the 10Th gametick the position is 500, and the speed is 100, then in the 11Th gametick the position will be 600. So where will you place your car when you render it? You could just take the position of the last gametick (in this case 500). But a better way is to predict where the car would be at exact 10.3, and this happens like this:
view_position = position + (speed * interpolation)
The car will then be rendered at position 530.
So basically the interpolation variable contains the value that is in between the previous gametick and the next one (previous = 0.0, next = 1.0). What you have to do then is make a "prediction" function where the car/camera/... would be placed at the render time. You can base this prediction function on the speed of the object, steering or rotation speed. It doesn't need to be complicated because we only use it to smooth things out in between the frames. It is indeed possible that an object gets rendered into another object right before a collision gets detected. But like we have seen before, the game is updated 25 frames per second, and so when this happens, the error is only shown for a fraction of a second, hardly noticeable to the human eye.
In most cases, update_game() will take far less time than display_game(). In fact, we can assume that even on slow hardware the update_game() function can run 25 times per second. So our game will handle player input and update the game state without much trouble, even if the game will only display 15 frames per second.
On fast hardware, the game will still run at a constant pace of 25 times per second, but the updating of the screen will be way faster than this. The interpolation/prediction method will create the visual appeal that the game is actually running at a high frame rate. The good thing is that you kind of cheat with your FPS. Because you don't update your game state every frame, only the visualization, your game will have a higher FPS than with the second method I described.
Making the game state independent of the FPS seems to be the best implementation for a game loop. However, you will have to implement a prediction function in display_game(), but this isn't that hard to achieve.
A game loop has more to it than you think. We've reviewed 4 possible implementations, and it seems that there is one of them which you should definitely avoid, and that's the one where a variable FPS dictates the game speed.
A constant frame rate can be a good and simple solution for mobile devices, but when you want to get everything the hardware has got, best use a game loop where the FPS is completely independent of the game speed, using a prediction function for high framerates.
If you don't want to bother with a prediction function, you can work with a maximum frame rate, but finding the right game update rate for both slow and fast hardware can be tricky.
Now go and start coding that fantastic game you are thinking of!
Koen Witters
우분투에서 설정하는 방법
sudo iptables -A INPUT
-m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A
INPUT -p tcp --dport ssh -j ACCEPT
sudo iptables
-A INPUT -p tcp --dport 80 -j ACCEPT
sudo
iptables -A INPUT -j DROP
sudo iptables -I INPUT
1 -i lo -j ACCEPT
sudo iptables -I INPUT
5 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: "
--log-level 7
sudo iptables -L -v
sudo
sh -c "iptables-save > /etc/iptables.rules"
vi /etc/network/interfaces
위의 내용에 아래의 두줄을 추가
pre-up iptables-restore <
/etc/iptables.rules
post-down iptables-save -c > /etc/iptables.rules
[출처] [Linux/Unix]iptables 방화벽|작성자 bestheroz
1)
방화벽 기본 정책
iptables 방화벽의 시작은 기본 정책을 수립하는 것이다. iptables를 이용하여 방화벽을 구성할 경우 두 가지 정책 중 한가지를 선택하면 된다. 일반적으로 모든 패킷에 대해서 무시하는 것이 방화벽의 기본 정책이다.
방화벽의 기본 정책
* 모든 것을 허용한 후 제한할
것을 거부한다.
* 모든 것을 거부한 후 필요한 것만 허용한다.
두 개중 일반적으로 모든 것을 막아버리는 것을 기본
정책으로 한다.
대부분의 리눅스 배포판은 모든 것을 거부하는 것을 기본 정책으로 채택하고 있으나, 페도라코어 리눅스의 경우는 모든 것을 허용하는 정책을 기본으로 하고 있다. 그러면 기본 정책으로 모든 것에 대해서 거부하는 정책을 택하여 다음과 같이 실행하여 기본 보안 정책을 수립한다.

iptables -L 명령으로 iptables의 테이블 상태를 점검할 수 있다. iptables -L 명령을 실행해 보면 INPUT과 FORWARD, OUTPUT 체인의 정책 모두 DROP으로 설정되 있음을 확인할 수 있다.

루프백으로 모든 패킷이 자유롭게 들어오고 나갈 수 있도록 다음과 같이 명령을 실행해 보자.
루프백 주소로 핑을 날리면 핑이 나감을 확인 할 수 있다. 핑 뿐만 아니라 로컬에서 제공하는 모든 네트워크 서비스에 접근할 수 있게 된다.
▶ iptables 사용법
iptables -A 체인명
-N : 새로운 체인 생성
-X : 비어있는 체인 제거
-P : 체인 정책 변경
-L : 체인의 규칙상태 보기
-F : 체인내의 모든 규칙 제거(방화벽 초기화)
-Z : 체인내의 모든 규칙의 패킷과 바이트의 카운트를 0으로 초기화
2) iptables 체인 종류
INPUT : 로컬로 들어오는 패킷(입력 패킷)
FORWARD : INPUT와 OUTPUT 역할, 라우터에 방화벽을 적용할 때 쓰임
OUTPUT : 외부로 나가는 패킷(출력 패킷)
INPUT 체인에 사용자 정의로 체인을 추가하여 INPUT 체인 대신에 사용할 수 있는데, 페도라 코어의 경우는 RH-Firewall-1-INPUT라는 사용자 정의 체인을 사용한다. 3개의 기본 체인(INPUT, OUTPUT, FORWARD)은 수정이나 삭제가 불가능하며, 사용자 정의 체인은 다음과 같은 방법으로 생성해 줄 수 있다.
3) iptables 다루기
▶ 방화벽 정책 초기화 # iptables -F
# iptables -X
# iptables -Z
▶ 기본 정책 설정
# iptables
-P INPUT DROP
# iptables -P OUTPUT DROP
#
iptables -P FORWARD DROP
▶ 사용자 정의 체인 생성 및 INPUT 체인에 추가
# iptables -N 사용자정의체인명
# iptables -A INPUT -j 사용자정의체인명
▶ 허용 정책 설정
루프백 접속 허용
다른 곳과 네트워크가 연결되어 있지 않더라도 시스템의 기본 네트워크이며 로컬 호스트의 인터페이스인 루프백에 대해서는 접속이 이뤄질 수 있도록 해야 하므로, 다음과 같이 설정한다.
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
내부 네트워크 접속
iptables -A fedora -s 192.168.0.0/24 -d 192.168.0.0/24 -j ACCEPT
iptables -A
OUTPUT -s 192.168.0.0/24 -d 192.168.0.0/24 -j ACCEPT
내부 -> 외부 접속
iptables -A fedora -s 외부주소 -p tcp -m tcp --sport 포트번호 -j ACCEPT
iptables -A OUTPUT -d 외부주소 -p tcp -m tcp --dport 포트
-j ACCEPT
① DNS 포트 허용
iptables -A fedora -p udp -m udp --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp -m udp
--dport 53 -j ACCEPT
② ICMP 핑 허용
iptables -A OUTPUT -o eth0 -p icmp --icmp-type echo-request -j ACCEPT
iptables -A fedora -i eth0 -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A OUTPUT -o eth0 -p
icmp --icmp-type echo-reply -j ACCEPT
③ SSH 포트 허용 ( 192.168.0.1 -> 172.16.1.20)
iptables -A fedora -s 172.16.1.20 -p tcp -m tcp --sport 22 -j ACCEPT
iptables -A OUTPUT -d 172.16.1.20 -p tcp -m tcp --dport 22
-j ACCEPT
④ HTTP 포트 허용
iptables -A fedora -i eth0 -p tcp -m tcp --sport 80 --dport 1024:65535 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m tcp
--sport 1024:65535 --dport 80 -j ACCEPT
⑤ FTP 포트 허용
* 명령(제어) 포트(tcp 21) 접속
iptables -A fedora -i eth0 -p tcp -m tcp --sport 21 --dport 1024:65535 -j ACCEPT
iptables -A OUTPUT -o eth0 -p
tcp -m tcp --sport 1024:65535 --dport 21 -j ACCEPT
*데이터 포트(tcp20) 접속(능동 모드 접속)
iptables -A fedora -i eth0 -p tcp -m tcp --sport 21 --dport 1024:65535 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m tcp --sport 1024:65535 --dport 21 -j ACCEPT
*데이터 포트(tcp 1024이상의
포트) (Passive 모드 접속)
iptables -A fedora -i eth0 -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -j ACCEPT
iptables
-A OUTPUT -o eth0 -p tcp -m tcp --sport 1024:65535 --dport 1024:65535 -j ACCEPT
외부 -> 내부 접속
① SSH 포트 허용
iptables -A fedora -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m tcp --sport 22 -j ACCEPT
② http 포트 허용
iptables -A fedora -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -o eth0 0p
tcp -m tcp --sport 80 -j ACCEPT
③ ftp 포트 허용 ( passive mode)
iptables -A fedora -i eth0 -p tcp -m tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m tcp --sport 21 -j ACCEPT
iptables -A fedora -i eth0 -p tcp -m tcp --dport 1024:65535 -j ACCEPT
iptables -A
OUTPUT -o eth0 -p tcp -m tcp --sport 1024:65535 -j ACCEPT