http://www.ioncannon.net/system-administration/59/php-rrdtool-tutorial/
On a number of occasions I've used RRDTool to graph network traffic and the like. A few years ago when I started using cacti I started wondering how to make the graphs myself. Creating the graphs on the command line isn't that hard once you know how to set things up and it turns out doing the same in PHP is just as easy.
For this tutorial I'm going to assume you understand how to get RRDTool installed and working from the command line. If not you should take a look at this tutorial (if you are in a hurry look at the "A Real World Example" section) or any of the tutorials on this page.
Setup and introduction
You need to have PHP compiled with RRDTool support to run the following PHP examples. If you compile PHP by hand then see: how to build the php rrdtool extension by hand. If you are using a distribution's pre-compiled PHP binary you should be able to install a second package with RRDTool support. You can verify that your PHP install is ready to go by running this:
Then search for "rrdtool" in the output and make sure that "rrdtool support" is enabled.
While going through each of the following steps you will notice that each call takes a couple of parameters and then one parameter that is just a string of options. The string of options is exactly how it is for generating/updating/graphing RRDs from the command line. This makes for a consistent interface for the different languages that have RRDTool support.
Creating a RRD
We first need to create a database for our data. For these examples I will be creating a database that could be used for generating network graphs. This database is created for updates every 5 minutes (300 seconds), has input and output counters that store data for the average and max counts and stores enough samples for hourly, daily, monthly and yearly graphs of both average and max.
$fname = "net.rrd";
$opts = array( "--step", "300", "--start", 0,
"DS:input:COUNTER:600:U:U",
"DS:output:COUNTER:600:U:U",
"RRA:AVERAGE:0.5:1:600",
"RRA:AVERAGE:0.5:6:700",
"RRA:AVERAGE:0.5:24:775",
"RRA:AVERAGE:0.5:288:797",
"RRA:MAX:0.5:1:600",
"RRA:MAX:0.5:6:700",
"RRA:MAX:0.5:24:775",
"RRA:MAX:0.5:288:797"
);
$ret = rrd_create($fname, $opts, count($opts));
if( $ret == 0 )
{
$err = rrd_error();
echo "Create error: $err\n";
}
?>
After running you will have a file called net.rrd in the current directory. This is your RRD and will contain all the samples for your graphs.
For more information on the options to rrd_create see: rrdcreate
Updating a RRD
The next step is to update your RRD on the frequency you set when you created it. In the case above the frequency was set to 5 minutes (300 seconds). The following script generates random input and output values as input to the update function, sleeps for 300 seconds and then loops.
$fname = "net.rrd";
$total_input_traffic = 0;
$total_output_traffic = 0;
while(true)
{
$total_input_traffic += rand(10000, 15000);
$total_output_traffic += rand(10000, 30000);
echo time() . ": " . $total_input_traffic . " and " . $total_output_traffic . "\n";
$ret = rrd_update($fname, "N:$total_input_traffic:$total_output_traffic");
if( $ret == 0 )
{
$err = rrd_error();
echo "ERROR occurred: $err\n";
}
sleep(300);
}
?>
Your input and output values could be pulled from anywhere here, I just wanted to have a source that would work for anyone who wanted to try the script.
After letting this script run for a few hours you can run the following shell script to see what type of data you have collected so far:
For more information on the options to rrd_update here: rrdupdate
END=`date +%s`
START=`echo $END-3600|bc` # over the hour
rrdtool fetch net.rrd AVERAGE --start $START --end $END
That should display the average sample values for the last hour.
Displaying RRD data as a graph
Now that you have data in your RRD you will want to graph it. The following code will graph the average input and output for 1 day as well as the max for that day.
$opts = array( "--start", "-1d", "--vertical-label=B/s",
"DEF:inoctets=net.rrd:input:AVERAGE",
"DEF:outoctets=net.rrd:output:AVERAGE",
"AREA:inoctets#00FF00:In traffic",
"LINE1:outoctets#0000FF:Out traffic\\r",
"CDEF:inbits=inoctets,8,*",
"CDEF:outbits=outoctets,8,*",
"COMMENT:\\n",
"GPRINT:inbits:AVERAGE:Avg In traffic\: %6.2lf %Sbps",
"COMMENT: ",
"GPRINT:inbits:MAX:Max In traffic\: %6.2lf %Sbps\\r",
"GPRINT:outbits:AVERAGE:Avg Out traffic\: %6.2lf %Sbps",
"COMMENT: ",
"GPRINT:outbits:MAX:Max Out traffic\: %6.2lf %Sbps\\r"
);
$ret = rrd_graph("net_1d.gif", $opts, count($opts));
if( !is_array($ret) )
{
$err = rrd_error();
echo "rrd_graph() ERROR: $err\n";
}
?>
You should end up with a file named net_1d.gif in your working directory that looks something like: 
You can also do weekly and monthly graphs by changing the start parameter to -1w or -1m:
For the impatient you can download my net.rrd file and try the graphs for yourself.
See the other tutorials for more information on the options you have for graphing.
For more information on the options to rrd_graph see: rrdgraph
자바스크립트에서 스트링관련해서 자주 쓰이는 함수들을 정리해 놓은 포스트가 있어 소개합니다.
이정도면 유용하게 활용할수 있을것 같네요.
1 /*--------------------------------------------------------------------------------*\
2 * JavaScript framework, version 2.0
3 *
4 * Date : 2006. 08. 15.
5 * Copyright 1998-2007 by Vricks Studio All right reserved.
6 * @author Jeff Yang routine@vricks.com
7 * 자주 쓰이는 스트링 관련 prototype관련 정리
8 \*--------------------------------------------------------------------------------*/
9
10 /*--------------------------------------------------------------------------------*\
11 * String prototype
12 \*--------------------------------------------------------------------------------*/
13 //-----------------------------------------------------------------------------
14 // 문자의 좌, 우 공백 제거
15 // @return : String
16 //-----------------------------------------------------------------------------
17 String.prototype.trim = function() {
18 return this.replace(/(^\s*)|(\s*$)/g, "");
19 }
20 //-----------------------------------------------------------------------------
21 // 문자의 좌 공백 제거
22 // @return : String
23 //-----------------------------------------------------------------------------
24 String.prototype.ltrim = function() {
25 return this.replace(/(^\s*)/, "");
26 }
27 //-----------------------------------------------------------------------------
28 // 문자의 우 공백 제거
29 // @return : String
30 //-----------------------------------------------------------------------------
31 String.prototype.rtrim = function() {
32 return this.replace(/(\s*$)/, "");
33 }
34 //-----------------------------------------------------------------------------
35 // 문자열의 byte 길이 반환
36 // @return : int
37 //-----------------------------------------------------------------------------
38 String.prototype.byte = function() {
39 var cnt = 0;
40 for (var i = 0; i < this.length; i++) {
41 if (this.charCodeAt(i) > 127)
42 cnt += 2;
43 else
44 cnt++;
45 }
46 return cnt;
47 }
48 //-----------------------------------------------------------------------------
49 // 정수형으로 변환
50 // @return : String
51 //-----------------------------------------------------------------------------
52 String.prototype.int = function() {
53 if(!isNaN(this)) {
54 return parseInt(this);
55 }
56 else {
57 return null;
58 }
59 }
60 //-----------------------------------------------------------------------------
61 // 숫자만 가져 오기
62 // @return : String
63 //-----------------------------------------------------------------------------
64 String.prototype.num = function() {
65 return (this.trim().replace(/[^0-9]/g, ""));
66 }
67 //-----------------------------------------------------------------------------
68 // 숫자에 3자리마다 , 를 찍어서 반환
69 // @return : String
70 //-----------------------------------------------------------------------------
71 String.prototype.money = function() {
72 var num = this.trim();
73 while((/(-?[0-9]+)([0-9]{3})/).test(num)) {
74 num = num.replace((/(-?[0-9]+)([0-9]{3})/), "$1,$2");
75 }
76 return num;
77 }
78 //-----------------------------------------------------------------------------
79 // 숫자의 자리수(cnt)에 맞도록 반환
80 // @return : String
81 //-----------------------------------------------------------------------------
82 String.prototype.digits = function(cnt) {
83 var digit = "";
84 if (this.length < cnt) {
85 for(var i = 0; i < cnt - this.length; i++) {
86 digit += "0";
87 }
88 }
89 return digit + this;
90 }
91 //-----------------------------------------------------------------------------
92 // " -> " ' -> '로 바꾸어서 반환
93 // @return : String
94 //-----------------------------------------------------------------------------
95 String.prototype.quota = function() {
96 return this.replace(/"/g, """).replace(/'/g, "'");
97 }
98 //-----------------------------------------------------------------------------
99 // 파일 확장자만 가져오기
100 // @return : String
101 //-----------------------------------------------------------------------------
102 String.prototype.ext = function() {
103 return (this.indexOf(".") < 0) ? "" : this.substring(this.lastIndexOf(".") + 1, this.length);
104 }
105 //-----------------------------------------------------------------------------
106 // URL에서 파라메터 제거한 순수한 url 얻기
107 // @return : String
108 //-----------------------------------------------------------------------------
109 String.prototype.uri = function() {
110 var arr = this.split("?");
111 arr = arr[0].split("#");
112 return arr[0];
113 }
114
115 /*---------------------------------------------------------------------------------*\
116 * 각종 체크 함수들
117 \*---------------------------------------------------------------------------------*/
118 //-----------------------------------------------------------------------------
119 // 정규식에 쓰이는 특수문자를 찾아서 이스케이프 한다.
120 // @return : String
121 //-----------------------------------------------------------------------------
122 String.prototype.meta = function() {
123 var str = this;
124 var result = ""
125 for(var i = 0; i < str.length; i++) {
126 if((/([\$\(\)\*\+\.\[\]\?\\\^\{\}\|]{1})/).test(str.charAt(i))) {
127 result += str.charAt(i).replace((/([\$\(\)\*\+\.\[\]\?\\\^\{\}\|]{1})/), "\\$1");
128 }
129 else {
130 result += str.charAt(i);
131 }
132 }
133 return result;
134 }
135 //-----------------------------------------------------------------------------
136 // 정규식에 쓰이는 특수문자를 찾아서 이스케이프 한다.
137 // @return : String
138 //-----------------------------------------------------------------------------
139 String.prototype.remove = function(pattern) {
140 return (pattern == null) ? this : eval("this.replace(/[" + pattern.meta() + "]/g, \"\")");
141 }
142 //-----------------------------------------------------------------------------
143 // 최소 최대 길이인지 검증
144 // str.isLength(min [,max])
145 // @return : boolean
146 //-----------------------------------------------------------------------------
147 String.prototype.isLength = function() {
148 var min = arguments[0];
149 var max = arguments[1] ? arguments[1] : null;
150 var success = true;
151 if(this.length < min) {
152 success = false;
153 }
154 if(max && this.length > max) {
155 success = false;
156 }
157 return success;
158 }
159 //-----------------------------------------------------------------------------
160 // 최소 최대 바이트인지 검증
161 // str.isByteLength(min [,max])
162 // @return : boolean
163 //-----------------------------------------------------------------------------
164 String.prototype.isByteLength = function() {
165 var min = arguments[0];
166 var max = arguments[1] ? arguments[1] : null;
167 var success = true;
168 if(this.byte() < min) {
169 success = false;
170 }
171 if(max && this.byte() > max) {
172 success = false;
173 }
174 return success;
175 }
176 //-----------------------------------------------------------------------------
177 // 공백이나 널인지 확인
178 // @return : boolean
179 //-----------------------------------------------------------------------------
180 String.prototype.isBlank = function() {
181 var str = this.trim();
182 for(var i = 0; i < str.length; i++) {
183 if ((str.charAt(i) != "\t") && (str.charAt(i) != "\n") && (str.charAt(i)!="\r")) {
184 return false;
185 }
186 }
187 return true;
188 }
189 //-----------------------------------------------------------------------------
190 // 숫자로 구성되어 있는지 학인
191 // arguments[0] : 허용할 문자셋
192 // @return : boolean
193 //-----------------------------------------------------------------------------
194 String.prototype.isNum = function() {
195 return (/^[0-9]+$/).test(this.remove(arguments[0])) ? true : false;
196 }
197 //-----------------------------------------------------------------------------
198 // 영어만 허용 - arguments[0] : 추가 허용할 문자들
199 // @return : boolean
200 //-----------------------------------------------------------------------------
201 String.prototype.isEng = function() {
202 return (/^[a-zA-Z]+$/).test(this.remove(arguments[0])) ? true : false;
203 }
204 //-----------------------------------------------------------------------------
205 // 숫자와 영어만 허용 - arguments[0] : 추가 허용할 문자들
206 // @return : boolean
207 //-----------------------------------------------------------------------------
208 String.prototype.isEngNum = function() {
209 return (/^[0-9a-zA-Z]+$/).test(this.remove(arguments[0])) ? true : false;
210 }
211 //-----------------------------------------------------------------------------
212 // 숫자와 영어만 허용 - arguments[0] : 추가 허용할 문자들
213 // @return : boolean
214 //-----------------------------------------------------------------------------
215 String.prototype.isNumEng = function() {
216 return this.isEngNum(arguments[0]);
217 }
218 //-----------------------------------------------------------------------------
219 // 아이디 체크 영어와 숫자만 체크 첫글자는 영어로 시작 - arguments[0] : 추가 허용할 문자들
220 // @return : boolean
221 //-----------------------------------------------------------------------------
222 String.prototype.isUserid = function() {
223 return (/^[a-zA-z]{1}[0-9a-zA-Z]+$/).test(this.remove(arguments[0])) ? true : false;
224 }
225 //-----------------------------------------------------------------------------
226 // 한글 체크 - arguments[0] : 추가 허용할 문자들
227 // @return : boolean
228 //-----------------------------------------------------------------------------
229 String.prototype.isKor = function() {
230 return (/^[가-힣]+$/).test(this.remove(arguments[0])) ? true : false;
231 }
232 //-----------------------------------------------------------------------------
233 // 주민번호 체크 - arguments[0] : 주민번호 구분자
234 // XXXXXX-XXXXXXX
235 // @return : boolean
236 //-----------------------------------------------------------------------------
237 String.prototype.isJumin = function() {
238 var arg = arguments[0] ? arguments[0] : "";
239 var jumin = eval("this.match(/[0-9]{2}[01]{1}[0-9]{1}[0123]{1}[0-9]{1}" + arg + "[1234]{1}[0-9]{6}$/)");
240 if(jumin == null) {
241 return false;
242 }
243 else {
244 jumin = jumin.toString().num().toString();
245 }
246 // 생년월일 체크
247 var birthYY = (parseInt(jumin.charAt(6)) == (1 ||2)) ? "19" : "20";
248 birthYY += jumin.substr(0, 2);
249 var birthMM = jumin.substr(2, 2) - 1;
250 var birthDD = jumin.substr(4, 2);
251 var birthDay = new Date(birthYY, birthMM, birthDD);
252 if(birthDay.getYear() % 100 != jumin.substr(0,2) || birthDay.getMonth() != birthMM || birthDay.getDate() != birthDD) {
253 return false;
254 }
255 var sum = 0;
256 var num = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5]
257 var last = parseInt(jumin.charAt(12));
258 for(var i = 0; i < 12; i++) {
259 sum += parseInt(jumin.charAt(i)) * num[i];
260 }
261 return ((11 - sum % 11) % 10 == last) ? true : false;
262 }
263 //-----------------------------------------------------------------------------
264 // 외국인 등록번호 체크 - arguments[0] : 등록번호 구분자
265 // XXXXXX-XXXXXXX
266 // @return : boolean
267 //-----------------------------------------------------------------------------
268 String.prototype.isForeign = function() {
269 var arg = arguments[0] ? arguments[0] : "";
270 var jumin = eval("this.match(/[0-9]{2}[01]{1}[0-9]{1}[0123]{1}[0-9]{1}" + arg + "[5678]{1}[0-9]{1}[02468]{1}[0-9]{2}[6789]{1}[0-9]{1}$/)");
271 if(jumin == null) {
272 return false;
273 }
274 else {
275 jumin = jumin.toString().num().toString();
276 }
277 // 생년월일 체크
278 var birthYY = (parseInt(jumin.charAt(6)) == (5 || 6)) ? "19" : "20";
279 birthYY += jumin.substr(0, 2);
280 var birthMM = jumin.substr(2, 2) - 1;
281 var birthDD = jumin.substr(4, 2);
282 var birthDay = new Date(birthYY, birthMM, birthDD);
283 if(birthDay.getYear() % 100 != jumin.substr(0,2) || birthDay.getMonth() != birthMM || birthDay.getDate() != birthDD) {
284 return false;
285 }
286 if((parseInt(jumin.charAt(7)) * 10 + parseInt(jumin.charAt(8))) % 2 != 0) {
287 return false;
288 }
289 var sum = 0;
290 var num = [2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5]
291 var last = parseInt(jumin.charAt(12));
292 for(var i = 0; i < 12; i++) {
293 sum += parseInt(jumin.charAt(i)) * num[i];
294 }
295 return (((11 - sum % 11) % 10) + 2 == last) ? true : false;
296 }
297 //-----------------------------------------------------------------------------
298 // 사업자번호 체크 - arguments[0] : 등록번호 구분자
299 // XX-XXX-XXXXX
300 // @return : boolean
301 //-----------------------------------------------------------------------------
302 String.prototype.isBiznum = function() {
303 var arg = arguments[0] ? arguments[0] : "";
304 var biznum = eval("this.match(/[0-9]{3}" + arg + "[0-9]{2}" + arg + "[0-9]{5}$/)");
305 if(biznum == null) {
306 return false;
307 }
308 else {
309 biznum = biznum.toString().num().toString();
310 }
311 var sum = parseInt(biznum.charAt(0));
312 var num = [0, 3, 7, 1, 3, 7, 1, 3];
313 for(var i = 1; i < 8; i++) sum += (parseInt(biznum.charAt(i)) * num[i]) % 10;
314 sum += Math.floor(parseInt(parseInt(biznum.charAt(8))) * 5 / 10);
315 sum += (parseInt(biznum.charAt(8)) * 5) % 10 + parseInt(biznum.charAt(9));
316 return (sum % 10 == 0) ? true : false;
317 }
318 //-----------------------------------------------------------------------------
319 // 법인 등록번호 체크 - arguments[0] : 등록번호 구분자
320 // XXXXXX-XXXXXXX
321 // @return : boolean
322 //-----------------------------------------------------------------------------
323 String.prototype.isCorpnum = function() {
324 var arg = arguments[0] ? arguments[0] : "";
325 var corpnum = eval("this.match(/[0-9]{6}" + arg + "[0-9]{7}$/)");
326 if(corpnum == null) {
327 return false;
328 }
329 else {
330 corpnum = corpnum.toString().num().toString();
331 }
332 var sum = 0;
333 var num = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
334 var last = parseInt(corpnum.charAt(12));
335 for(var i = 0; i < 12; i++) {
336 sum += parseInt(corpnum.charAt(i)) * num[i];
337 }
338 return ((10 - sum % 10) % 10 == last) ? true : false;
339 }
340 //-----------------------------------------------------------------------------
341 // 이메일의 유효성을 체크
342 // @return : boolean
343 //-----------------------------------------------------------------------------
344 String.prototype.isEmail = function() {
345 return (/\w+([-+.]\w+)*@\w+([-.]\w+)*\.[a-zA-Z]{2,4}$/).test(this.trim());
346 }
347 //-----------------------------------------------------------------------------
348 // 전화번호 체크 - arguments[0] : 전화번호 구분자
349 // @return : boolean
350 //-----------------------------------------------------------------------------
351 String.prototype.isPhone = function() {
352 var arg = arguments[0] ? arguments[0] : "";
353 return eval("(/(02|0[3-9]{1}[0-9]{1})" + arg + "[1-9]{1}[0-9]{2,3}" + arg + "[0-9]{4}$/).test(this)");
354 }
355 //-----------------------------------------------------------------------------
356 // 핸드폰번호 체크 - arguments[0] : 핸드폰 구분자
357 // @return : boolean
358 //-----------------------------------------------------------------------------
359 String.prototype.isMobile = function() {
360 var arg = arguments[0] ? arguments[0] : "";
361 return eval("(/01[016789]" + arg + "[1-9]{1}[0-9]{2,3}" + arg + "[0-9]{4}$/).test(this)");
362 }
http://www.cyberciti.biz/tips/openssh-deny-or-restrict-access-to-users-and-groups.html
OpenSSH has two directives for allowing and denying ssh user access.
DenyUsers user1 user2 user3
Use to block user login. You can use wild cards as well as user1@somedomain.com (user1 is not allowed to login from somedomain.com host) pattern.
DenyGroups group1 group2
A list of group names, if user is part of primary of supplementary group login access is denied. You can use wildcards.
Please note that you cannot use a numeric group or username ID. If these directives are not used, default is to allow everyone.
AllowUsers user1 user2
This directive is opposite of DenyUsers directive.
AllowGroups group1 group2
This directive is opposite of DenyGroups directive.
You should always block access to root user/group:
Open /etc/ssh/sshd_config file:
# vi /etc/ssh/sshd_config
Append following names (directives):
DenyUsers root finadmin
DenyGroups root finadmin
Make sure at least one user is allowed to use ’su -’ command.
Save the file and restart the sshd.
This is a secure setup and you are restricting the users allowed to access the system via SSH with four above directives.
Please note that if you want to deny or allow access to large number of users consider SSH PAM configuration (ideal for ISPs and Web hosting service providers). PAM allows you to store usernames using text files (you do not have to mess up with ssh configuration file).
Please subscribe to our free e-mail newsletter or full RSS feed to get all updates. Or just leave a reply/comment ( 12 ).
<HEAD>
<TITLE>SEEBOX Network Monitoring System</TITLE>
<meta HTTP-EQUIV="REFRESH" CONTENT=50>
<meta HTTP-EQUIV="Expires" Content=0>
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
</HEAD>
<FRAMESET cols="100%">
<FRAME src="http://www.naver.com/">
</FRAMESET>
</HTML
/etc/X11/xorg.conf
-------------------------------------------------------------------
Section "ServerLayout"
Identifier "Default Layout"
Screen 0 "Screen0" 0 0
Screen 1 "Screen1" RightOf "Screen0"
InputDevice "Mouse0" "CorePointer"
InputDevice "Keyboard0" "CoreKeyboard"
Option "BlankTime" "0" # Blank the screen in 10 minutes (Fake)
Option "StandbyTime" "0" # Turn off screen in 20 minutes (DPMS)
Option "SuspendTime" "0" # Full hibernation in 30 minutes (DPMS)
Option "OffTime" "0" # Turn off DPMS monitor (DPMS)
EndSection
----------------------------------------------------------------------
* 위의 설정만으로 모니터꺼짐이 동작하지는 않을것이나 부가적으로 추가한다면
(1) gnome screen saver uninstall
# rpm -e gnome-screensaver
(2) xset command를 .xinitrc 에 추가함
export DISPLAY=:0.0
xset -display :0.0 -dpms
xset -display :0.0 s off
xset -display :0.0 s noblank
xset -display :0.0 s noexpose
export DISPLAY=:0.1
xset -display :0.1 -dpms
xset -display :0.1 s off
xset -display :0.1 s noblank
xset -display :0.1 s noexpose
모니터가 한개이면 -display는 없어도 될것임....
/etc/inittab
------------------------------------------------------------
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty --autologin root tty1
2:2345:respawn:/sbin/mingetty --autologin root tty2
3:2345:respawn:/sbin/mingetty --autologin root tty3
4:2345:respawn:/sbin/mingetty --autologin root tty4
5:2345:respawn:/sbin/mingetty --autologin root tty5
6:2345:respawn:/sbin/mingetty --autologin root tty6
-------------------------------------------------------------
2. 특정 console에서만 어플리케이션 자동실행
/root/.bash_profile or /etc/profile
-------------------------------------------------------------
if `tty | grep tty1 >/dev/null` ; then
startx &
sleep 10
export DISPLAY=:0.0
thunderbird &
export DISPLAY=:0.1
firefox file:///opt/monitoring/monitoring.html &
fi
--------------------------------------------------------------
PuTTY 를 사용하여, 특정 사설 네트워크의 네트웍 자원에 쉽게 접근할 수 있는 방법을 소개한다. 전제조건으로, 당연히, 그 사설 네트워크 안의 리눅스 서버에 SSH 를 통해 접근할 수 있어야한다.
- Connection - SSH - Tunnels 섹션의 Port Forwarding 에 적절한 값을 입력해야한다.
- Add new forwarded port: 부분을 잘 살펴본다. Source port 는 현재 내 시스템에 생길 입구 포트를 의미하며, Destination 이 앞서 지정한 포트로 접속했을 때의 출구를 의미한다. Source port 에 51234 정도를 입력해주고 (잘 안 쓰는 포트), Destination port 에 192.168.57.3:3389 를 입력해주자(여기서 사용된 IP 는 V 모 서버의 사설 네트워크용 아이피이다). 설정 후 Add 버튼을 눌러 리스트에 추가하는 걸 잊지 말자.
- 평소대로 U 모 서버에 접속, 로그인한다. PuTTY 는 계속 켜져있어야한다.
- mstsc 프로그램을 켜고 localhost:51234 포트로 접속한다. V 모 서버의 3389 포트로 접근한 것과 같은 효과가 난다.
- 관리자 권한이 필요한 거창한 방화벽 설정 없이도 손쉽게 포트를 포워딩 할 수 있다.
- 네트웍을 흐르는 정보가 SSH 위에서 돌아다니므로, 안전하게 데이터를 주고받을 수 있다.
- SSH 암호화를 거치는 과정에서 속도가 약간 떨어질 수 있다.
- 그래도 조금은 귀찮다.
그 밖의 활용방법 #
방화벽 뚫기 삽질기 #
요약 #
사전 요구사항 #
- 서버 T 의 sshd 에서 GatewayPorts 설정이 yes 로 되어 있어야한다. (즉 서버 T 의 root 권한으로 sshd 의 설정을 바꿔줄 필요가 있다. 자세한 방법은 아래에서.)
터널링 설정 #
- Source port : 서버 T 에서 연결을 받아들일(Listening) 포트를 설정한다. 여기서는 58080 으로 설정한다고 하자.
- Destination port : Source Port 로 들어온 연결이 어느 쪽으로 흐를지 출구를 설정한다. SSH Client 가 동작하는 컴퓨터에서 접근 가능한 컴퓨터라면 어디든지 OK. 여기서는 컴퓨터 A 에서 웹서버가 돈다고 가정하고 있으므로, 127.0.0.1:80 이 되겠다.
- Local/Remote/Dynamic 중 Remote 를 설정한다.
위의 설정을 잘 끝낸 후 접속을 성공시키고 netstat 등을 실행시켜보면, 58080 포트(Source Port 에서 지정한 포트) 에서 연결을 받아들이고 있음을 확인할 수 있다. telnet 이나 웹브라우저(w3m, lynx)등을 사용하여 localhost:58080 으로 접속해보면 성공적으로 컴퓨터 A 의 웹서버에 접속할 수 있을 것이다.
여기서 문제는, 대부분의 서버에서는 이 58080 포트를 통해 다른 컴퓨터들은 접속할 수 없다는 것이다. netstat -an 등을 수행해본 결과를 유심히 보면 알겠지만, listening 포트가 127.0.0.1:58080 등으로, localhost 에서만 접속할 수 있는 포트로 binding 되어있기 때문이다. 다른 컴퓨터들이 서버 T 의 58080 포트를 통해 컴퓨터 A 에 접근하기 위해선, 0.0.0.0:58080 에 bind 되어있어야한다. 이는 sshd 의 설정을 바꿔서 해결할 수 있다.
sshd 설정을 변경하여 다른 컴퓨터로부터의 접속 받아들이기 #
2.4. XF86Config Tuning
There are essentially two different types of screen blanking that can be performed under X-Windows: BlankTime and DPMS. The first is simply a fake "blanking" effect that doesn't actually save any power. The others are specific only to DPMS-compliant monitors, and must be specifically enabled to take effect. They are located in your XF86Config file, which normally resides in /etc/X11/XF86Config.
DPMS (Display Power Management Signaling) is a standard to reduce power consumption in monitors [2]. Typically, both the monitor and the video card must support the DPMS standard in order to receive any benefit from it. DPMS specifies four modes of operation (in order of increasing power savings): "Normal", "Standby", "Suspend" and "Off". Two signal lines, "Horizontal Sync" and "Vertical Sync" provide a method for signaling these four different states to a DPMS monitor.
If you have a DPMS-compliant monitor, you might want to try enabling support for it under the Monitor section of your XF86Config file:
Section "Monitor" [... other values here ...] Option "DPMS" EndSection |
To manipulate the DPMS functions, you can create/modify the following items in the ServerLayout section.
Section "ServerLayout" Option "BlankTime" "10" # Blank the screen in 10 minutes (Fake) Option "StandbyTime" "20" # Turn off screen in 20 minutes (DPMS) Option "SuspendTime" "30" # Full hibernation in 30 minutes (DPMS) Option "OffTime" "40" # Turn off DPMS monitor (DPMS) EndSection |
BlankTime is not actually a power saving level at all. The screen is sent a "fake" blanking effect and defaults to activate after 10 minutes. Alternately, it can indicate the number of minutes until the screensaver should activate. It has nothing to do with DPMS.
StandbyTime is a very minor power saving level. This setting usually involves blanking the screen by turning off the electron (RGB) gun. However, the power supply is left on and the tube filaments energized. When you need to use the monitor again, the monitor will come back on very quickly. This option requires DPMS monitor/video-card support and defaults to 20 minutes under X-Windows. Also known as hsync suspend mode, since the horizontal sync signal is turned off to signal this power management state to a DPMS monitor.
SuspendTime is a very strong low power alternative. This setting usually involves the same power conservation as StandbyTime, however in addition the power supply is turned off. This option requires DPMS monitor/video-card support and defaults to 30 minutes under X-Windows. Also known as vsync suspend mode, since the vertical sync signal is turned off to signal this power management state to a DPMS monitor.
OffTime usually means just that. The computer monitor is turned off. A small auxiliary circuit stays on to monitor the signals from the computer to turn the monitor back on when data needs to be displayed to the screen. Obviously, this keeps power consumption to a bare minimum (zero). While the power saving is substantial, to reactivate the monitor may take up to 8-10 seconds. This option requires DPMS monitor/video-card support and defaults to 40 minutes under X-Windows. Both the horizontal and vertical sync signals are turned off to signal this power management state to a DPMS monitor.
After activating your changes and restarting X-Windows, you might want to examine your logfile to see if your video card has any problems with your changes:
$ egrep "^\(WW|EE\)" /var/log/XFree86.0.log |
There may be additional options that you can enable for your specific video card/chip driver; see the XFree86 Documentation website for specifics.
Of course, all of this can also be activated "on-the-fly" by using xset(1). If you don't have access to your system's XF86Config file, a good place to put these commands would be in your ~/.Xsession or ~/.xinitrc file.
$ xset -dpms # Disable DPMS $ xset +dpms # Enable DPMS $ xset s off # Disable screen blanking $ xset s 150 # Blank the screen after 150 seconds $ xset dpms 300 600 900 # Set standby, suspend, & off times (in seconds) $ xset dpms force standby # Immediately go into standby mode $ xset dpms force suspend # Immediately go into suspend mode $ xset dpms force off # Immediately turn off the monitor $ xset -q # Query current settings |
If instead you're using the Linux console (not X-Windows), you'll want to use setterm(1):
$ setterm -blank 10 # Blank the screen in 10 minutes $ setterm -powersave on # Put the monitor into VESA power saving mode $ setterm -powerdown 20 # Set the VESA powerdown to 20 minutes |
2.5. Energy Star
Energy Star is a United States government-backed program to promote energy efficiency standards. Of interest:
-
An ENERGY STAR qualified computer, in sleep mode, uses 70% less electricity than computers without power management features.
-
An ENERGY STAR qualified monitor, in sleep mode, uses 90% less electricity than monitors without power management features.
Typically, Energy Star savings is accomplished by other power management settings and is not, in and of itself, a power management technique.

이올린에 북마크하기
Prev
Rss Feed