<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0YHQX04fSp7ImA9WhRaEUg.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068</id><updated>2012-02-13T09:45:30.335-08:00</updated><category term="VBScript" /><category term="Python" /><category term="Xen" /><category term="X Window" /><category term="Issue Tracker" /><category term="Performance" /><category term="DNS" /><category term="IT Talk" /><category term="SQL Injection" /><category term="C" /><category term="Postfix" /><category term="SQL Server" /><category term="Security" /><category term="command" /><category term="English Vocabulary" /><category term="Redundancy" /><category term="VPN" /><category term="Web Development" /><category term="Computer Terminology" /><category term="PowerShell" /><category term="Backup" /><category term="Programming Talk" /><category term="Debugging" /><category term="Mac OS X" /><category term="Unix-like Tips" /><category term="Batch" /><category term="C# .NET" /><category term="vim" /><category term="Apache" /><category term="Miscellaneous (Others)" /><category term="HTML/CSS" /><category term="Virtualization" /><category term="News" /><category term="Mail" /><category term="Revision Control" /><category term="jQuery" /><category term="Script" /><category term="MySQL" /><category term="Nginx" /><category term="Golden Saying Quotation" /><category term="Load Balancing" /><category term="Windows MIS" /><category term="XML" /><category term="FreeBSD" /><category term="Perl" /><category term="IIS" /><category term="Exchange Server" /><category term="PHP" /><category term="Drupal" /><category term="Unicode" /><category term="Assembly" /><category term="iPhone" /><category term="PostgreSQL" /><category term="VMware" /><category term="Linux" /><category term="Tools" /><category term="Hardware" /><category term="Good Articles" /><category term="Reverse Engineering" /><category term="Ubuntu" /><category term="Bash" /><category term="VB .NET" /><category term="JavaScript" /><category term="Regular Expression" /><category term="tmp" /><category term="ToDo" /><title>Simple life, Complicated mind</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.ijun.org/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.ijun.org/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>1588</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ThereIsNoPlaceLike127001" /><feedburner:info uri="thereisnoplacelike127001" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0YHQX0-eyp7ImA9WhRaEUg.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-823806380781622567</id><published>2012-02-13T09:45:00.001-08:00</published><updated>2012-02-13T09:45:30.353-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-13T09:45:30.353-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ToDo" /><title>Drupal - Symfony - a PHP Web Development Framework.</title><content type="html">Drupal - Symfony - a PHP Web Development Framework.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://symfony.com/"&gt;http://symfony.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-823806380781622567?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/xa8jFlIomxk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/823806380781622567/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=823806380781622567" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/823806380781622567?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/823806380781622567?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/xa8jFlIomxk/drupal-symfony-php-web-development.html" title="Drupal - Symfony - a PHP Web Development Framework." /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/02/drupal-symfony-php-web-development.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QHQX8zeyp7ImA9WhRbEU4.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-4126247887312794349</id><published>2012-02-01T15:35:00.000-08:00</published><updated>2012-02-01T15:35:30.183-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-01T15:35:30.183-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="vim" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><title>Using vim + xdebug to debug php On FreeBSD</title><content type="html">&lt;b&gt;Using vim + xdebug to debug php On FreeBSD&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the scenario: You have multiple developers logged into a Linux server which is running Apache and PHP using Vim to write PHP code. They’re using error_log and echo statements to debug their code. It takes forever, it’s tedious and can result in bugs from forgotten debug statements. You stare enviously at .NET programmers with fancy debuggers (while you snicker knowing that you edit 10x faster with Vim anyways). But still, you know there has to be a better way.&lt;br /&gt;
&lt;br /&gt;
There is.&lt;br /&gt;
&lt;br /&gt;
Here’s how it works. You’re coding away in vim. You hit F5; Vim waits for a connection from the PHP server. You refresh the PHP page you’re working on. It attempts to contact Vim — connection successful. You are launched into a debugging session right inside Vim. You can step into, over, and out of statements, eval statements, get all variables in context, get and set properties, remove and set breakpoints, all on the fly. Finally, some real programming tools.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install VIM&lt;/b&gt;&lt;br /&gt;
&lt;blockquote&gt;# cd /usr/ports/editors/vim&lt;br /&gt;
# make WITH_PYTHON=yes install&lt;br /&gt;
# cp /usr/local/share/vim/vim72/vimrc_example.vim ~/.vimrc&lt;/blockquote&gt;&lt;br /&gt;
&lt;b&gt;Make sure your VIM supported Python:&lt;/b&gt;&lt;br /&gt;
# vim --version | grep -E 'python|sign'&lt;br /&gt;
&lt;br /&gt;
If you see "&lt;b&gt;+python&lt;/b&gt;" and "&lt;b&gt;+sign&lt;/b&gt;" you are good to go.&lt;br /&gt;
If you see "-python" and "-sign", please reinstall your vim with WITH_PYTHON=yes option&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install Xdebug client&lt;/b&gt;&lt;br /&gt;
Now that vim is ready, download the DBGp client script. Extract the two files (debugger.vim and debugger.py) to your vim plugin directory or your .vim home directory&lt;br /&gt;
&lt;br /&gt;
In Vim 7.2 compiled on FreeBSD, the default load-for-everyone plugin location is /usr/local/share/vim/vim72/plugin/, so you would put both files in that directory.&lt;br /&gt;
&lt;br /&gt;
Pick one of clients from:&lt;br /&gt;
DBGp client script: &lt;a href="http://www.vim.org/scripts/script.php?script_id=2508"&gt;http://www.vim.org/scripts/script.php?script_id=2508&lt;/a&gt;&lt;br /&gt;
DBGp client script: &lt;a href="http://www.vim.org/scripts/script.php?script_id=1929"&gt;http://www.vim.org/scripts/script.php?script_id=1929&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Copy debugger.vim and debugger.py to either one of following directories:&lt;br /&gt;
&lt;blockquote&gt;/usr/local/share/vim/vim72/plugin&lt;br /&gt;
or &lt;br /&gt;
~/.vim/plugin&lt;/blockquote&gt;&lt;br /&gt;
Try to run vim — if you get no errors, everything should be good. If you get an error, double check :version to make sure +python and +signs are there. If they are, post a comment here with the vi error you get. If they aren’t, the vim compilation/installation didn’t work — go back and try it again.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install xdebug (the server [engine])&lt;/b&gt;&lt;br /&gt;
&lt;blockquote&gt;# cd /usr/ports/devel/php-xdebug&lt;br /&gt;
# make install&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote style="background-color: #cccccc;"&gt;# vim /usr/local/etc/php.ini&lt;br /&gt;
[Zend]&lt;br /&gt;
zend_extension = /usr/local/lib/php/20060613/xdebug.so&lt;br /&gt;
&lt;br /&gt;
; This switch controls whether Xdebug should try to contact a debug client which is listening on the host and port as set with the settings xdebug.remote_host and xdebug.remote_port.&lt;br /&gt;
xdebug.remote_enable = 0&lt;br /&gt;
xdebug.remote_port = 9000&lt;br /&gt;
xdebug.remote_host = localhost&lt;br /&gt;
&lt;br /&gt;
; When this setting is set to on, the tracing of function calls will be enabled just before the script is run. This makes it possible to trace code in the auto_prepend_file.&lt;br /&gt;
xdebug.auto_trace = 1&lt;br /&gt;
xdebug.trace_output_dir = "/tmp/xdebug/log"&lt;br /&gt;
xdebug.collect_params = 4&lt;br /&gt;
&lt;br /&gt;
;xdebug.var_display_max_children = 128&lt;br /&gt;
;xdebug.var_display_max_data = 512&lt;br /&gt;
;xdebug.var_display_max_depth = 3&lt;br /&gt;
&lt;br /&gt;
; Enables Xdebug's profiler which creates files in the profile output directory. Those files can be read by KCacheGrind to visualize your data.&lt;br /&gt;
xdebug.profiler_enable = 1&lt;br /&gt;
xdebug.profiler_output_dir = "/tmp/xdebug/log"&lt;br /&gt;
&lt;br /&gt;
; Controls the protection mechanism for infinite recursion protection. The value of this setting is the maximum level of nested functions that are allowed before the script will be aborted.&lt;br /&gt;
xdebug.max_nesting_level = 100&lt;br /&gt;
&lt;br /&gt;
; shows a human readable / computer readable trace file.&lt;br /&gt;
xdebug.trace_format = 0&lt;br /&gt;
&lt;br /&gt;
; This setting tells Xdebug to gather information about which variables are used in a certain scope. This analysis can be quite slow as Xdebug has to reverse engineer PHP's opcode arrays. This setting will not record which values the different variables have, for that use xdebug.collect_params. This setting needs to be enabled only if you wish to use xdebug_get_declared_vars().&lt;br /&gt;
xdebug.collect_vars = 0&lt;br /&gt;
&lt;br /&gt;
; When set to '1' the trace files will be appended to, instead of being overwritten in subsequent requests.&lt;br /&gt;
; Note: this option can be useful if you could not find your function calls anywhere.&lt;br /&gt;
xdebug.trace_options = 1&lt;/blockquote&gt;&lt;br /&gt;
&lt;b&gt;Make sure xdebug is loaded by PHP&lt;/b&gt;&lt;br /&gt;
&lt;pre class="php" name="code"&gt;&amp;lt;?php
echo phpinfo();
?&amp;gt;&lt;/pre&gt;&lt;br /&gt;
Now, with your site being example.com, go to &lt;a href="http://example.com/index.php?XDEBUG_SESSION_START=1"&gt;http://example.com/index.php?XDEBUG_SESSION_START=1&lt;/a&gt; (Add &lt;b&gt;XDEBUG_SESSION_START=1&lt;/b&gt; after your script name). This will set a cookie in your browser which expires in 1 hour which tells the PHP XDebug module to try to make a connection every time a page loads to a debugging client which is listening on port 9000. The cool thing is that if it can’t make a connection, it just keeps loading the page, so there’s no issue just leaving the cookie on.&lt;br /&gt;
&lt;br /&gt;
Now go back to vim and press &lt;b&gt;F5&lt;/b&gt;. You should see a message like “&lt;b&gt;waiting for a new connection on port 9000 for 5 seconds…&lt;/b&gt;” at the bottom of the screen. You have five seconds to now &lt;b&gt;refresh the PHP page&lt;/b&gt;. This will create a connection between the debugger and client. Now you’re debugging. Follow the instructions in the Help window to step into, over and out of code. Press F5 to run the code until a breakpoint (which you can set using &lt;b&gt;:Bp&lt;/b&gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote style="color: red;"&gt;When I pressed F1, F2, or F3 keys, it toggles the character to either upper or lower case.&lt;br /&gt;
&lt;br /&gt;
To solve this problem, I changed following line:&lt;br /&gt;
map &amp;lt;F2&amp;gt; :python debugger_command('step_into')&amp;lt;cr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To:&lt;br /&gt;
map ^[[12~ :python debugger_command('step_into')&amp;lt;cr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note: press ctrl-v F2 to generate ^[[12~.&lt;/b&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_A-khMn5C-S8/SuDero5O-KI/AAAAAAAABbk/TsQ2MtJfrKM/s1600-h/vim_xdebug.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_A-khMn5C-S8/SuDero5O-KI/AAAAAAAABbk/TsQ2MtJfrKM/s640/vim_xdebug.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;But what if I have multiple developers on the same machine?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
No problem. Simply set g:debuggerPort in each developer’s .vimrc to get the client listening on a different port. So if you wanted one developer to connect on 9001 instead of the standard 9000, you would add this line to their .vimrc:&lt;br /&gt;
&lt;br /&gt;
let g:debuggerPort = 9001&lt;br /&gt;
&lt;br /&gt;
Getting the server to connect on a different port is a little trickier. You need to set a custom php.ini value (xdebug.remote_port) for each user. It works best if you’re using VirtualHost’s in Apache. Just add the following line to the VirtualHost section of your httpd.conf:&lt;br /&gt;
&lt;br /&gt;
php_value xdebug.remote_port 9001&lt;br /&gt;
&lt;br /&gt;
Now restart Apache and if you use that VirtualHost and that vi user, then they should connect successfully.&lt;br /&gt;
That’s about it&lt;br /&gt;
&lt;br /&gt;
Please post any questions or suggestions you may have. I hope this helps a few of you out there who want debugging tools but don’t want to give up Vim editing. Also be sure to post any alternate methods, or any patches or improvements to the remote PHP debugger vim script, and I’ll be sure to incorporate them.&lt;br /&gt;
&lt;br /&gt;
[Note: This is the first in a series of posts we'll be doing along the lines of tutorials, tools we've developed, tech commentary, and so on. Please feel free to subscribe, as well as leave any comments, thoughts or suggestions below so we can be sure to improve with each article! Thanks!]&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;use XDebugToolkit to convert the XDebug cachegrind (= “xdebug.log“) to a dot graph&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://code.google.com/p/xdebugtoolkit/"&gt;http://code.google.com/p/xdebugtoolkit/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
# svn co http://xdebugtoolkit.googlecode.com/svn/tags/0.1.3/xdebugtoolkit/ xdebugtoolkit&lt;br /&gt;
# ./cg2dot.py cachegrind.out.23328 &amp;gt; cachegrind.out.23328.dot&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/graphics/graphviz ; make install ; rehash&lt;br /&gt;
# dot -Tpng -otest.png&lt;br /&gt;
&lt;br /&gt;
Combine to one command:&lt;br /&gt;
# ./cg2dot.py cachegrind.out.23328 | dot -Tpng -otest.png&lt;br /&gt;
&lt;br /&gt;
this might be useful /usr/ports/graphics/py-pydot ??&lt;br /&gt;
&lt;br /&gt;
Windows version of Graphviz is also available at:&lt;br /&gt;
&lt;a href="http://www.graphviz.org/Download..php"&gt;http://www.graphviz.org/Download..php&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://code.google.com/p/jrfonseca/wiki/XDot"&gt;XDot&lt;/a&gt; - Interactive viewer for Graphviz dot files&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://valgrind.org/info/tools.html"&gt;CacheGrind&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://sourceforge.net/projects/wincachegrind/"&gt;WinCacheGrind (for Windows)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://code.google.com/p/cachegrindvisualizer/"&gt;CacheGrindvisualizer&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://graphviz.org/About.php"&gt;Graphviz&lt;/a&gt; - Graph Visualization Software&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://zvtm.sourceforge.net/zgrviewer.html"&gt;ZGRViewer&lt;/a&gt; - a GraphViz/DOT Viewer&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://en.wikipedia.org/wiki/DOT_language"&gt;Dot Language&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[] &lt;a href="http://en.wikipedia.org/wiki/Scalable_Vector_Graphics"&gt;Scalable Vector Graphics (SVG)&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://tech.blog.box.net/2007/06/20/how-to-debug-php-with-vim-and-xdebug-on-linux/"&gt;How to Debug PHP with Vim and XDebug on Linux&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-4126247887312794349?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/rW7nti29luc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/4126247887312794349/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=4126247887312794349" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/4126247887312794349?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/4126247887312794349?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/rW7nti29luc/using-vim-xdebug-to-debug-php-on.html" title="Using vim + xdebug to debug php On FreeBSD" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_A-khMn5C-S8/SuDero5O-KI/AAAAAAAABbk/TsQ2MtJfrKM/s72-c/vim_xdebug.PNG" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.ijun.org/2009/10/using-vim-xdebug-to-debug-php-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcBRnk5fCp7ImA9WhRbEU4.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-7093272638367741328</id><published>2012-02-01T15:14:00.000-08:00</published><updated>2012-02-01T15:14:17.724-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-01T15:14:17.724-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tools" /><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><category scheme="http://www.blogger.com/atom/ns#" term="ToDo" /><title>use ctags and vim on freebsd</title><content type="html">use ctags on freebsd&lt;br /&gt;
&lt;br /&gt;
There are two ctags on freebsd :&lt;br /&gt;
&lt;br /&gt;
ctags from base system : /usr/bin/ctags&lt;br /&gt;
exuberant ctags from ports : /usr/local/bin/exctags&lt;br /&gt;
&lt;br /&gt;
If you are linux programmer (like me), then exctags is what you are looking for.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install ctags from ports:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
cd /usr/ports/devel/ctags&lt;br /&gt;
make install clean&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Generate tags from current directory:&lt;/b&gt;&lt;br /&gt;
# cd /src/dir/&lt;br /&gt;
# /usr/local/bin/exctags -R&lt;br /&gt;
&lt;br /&gt;
Note: a new tags file will be generated under the current directory.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Generate tags from specified directory and store the tag file to the specified path:&lt;/b&gt;&lt;br /&gt;
# /usr/local/bin/exctags -R -f /tmp/tags /src/dir/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Let exctags to read *.module file as a php script for Drupal:&lt;/b&gt;&lt;br /&gt;
/usr/local/bin/exctags -R -f /tmp/tags --langmap=php:+.module.inc /src/dir/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit your ~/.vimrc:&lt;/b&gt;&lt;br /&gt;
" To display the tags for only the current active buffer:&lt;br /&gt;
let Tlist_Show_One_File=1&lt;br /&gt;
&lt;br /&gt;
" toggle the taglist window.&lt;br /&gt;
" Note: press ctrl-v F6 to generate ^[[17~&lt;br /&gt;
nnoremap &lt;silent&gt; ^[[17~ :TlistToggle&amp;lt;CR&amp;gt;&lt;br /&gt;
"nnoremap &lt;silent&gt; &amp;lt;F6&amp;gt; :TlistToggle&amp;lt;CR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Run this command in your vim:&lt;/b&gt;&lt;br /&gt;
:set tags=/tmp/tags&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Add this line to your ~/.vimrc:&lt;/b&gt;&lt;br /&gt;
set tags=/tmp/tags&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.codernotes.com/2011/202/use-ctags-on-freebsd/"&gt;http://www.codernotes.com/2011/202/use-ctags-on-freebsd/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-7093272638367741328?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/pFJS8HCRf9c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/7093272638367741328/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=7093272638367741328" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/7093272638367741328?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/7093272638367741328?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/pFJS8HCRf9c/use-ctags-on-freebsd.html" title="use ctags and vim on freebsd" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2011/11/use-ctags-on-freebsd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMFRn09fSp7ImA9WhRbEU8.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-2078009961666284464</id><published>2012-02-01T12:16:00.000-08:00</published><updated>2012-02-01T12:16:57.365-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-01T12:16:57.365-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ToDo" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><title>GNU GLOBAL 作為分析基礎</title><content type="html">GNU GLOBAL 作為分析基礎&lt;br /&gt;
by thinker&lt;br /&gt;
2 Columns&lt;br /&gt;
關鍵字:&lt;br /&gt;
coding&lt;br /&gt;
最近對程式碼分析 (reverse) 有一些想法，打算做一些小工具。如果從頭打造，大概得花個幾個月以上的時間，而且有許多現成的工具可以幫忙完成部分工作。其中最麻煩的工作大概就是 parse 程式碼， doxygen 已經做了我要的東西，應該直接利用就好了，但 doxygen 卻沒有輸出 raw data 。&lt;br /&gt;
&lt;br /&gt;
本來打算看 doxygen 的程式碼，從中攔截，並輸出我要的資料，但意外中發現 GNU GLOBAL 。 GNU GLOBAL 是類似 ctags 的工具，但提供許多 command line 的命令，可以查詢 symbol 的出處，被 reference 的位置等等，正是我所要的資訊，又是 command line 工具，更易於整合。&lt;br /&gt;
&lt;br /&gt;
雖然和 ctags 相似，但 ctags 只產生 DB ，卻沒有讀取 DB 的 command line 工具，另外 ctags 也沒有產生 reference 的資訊。各方面而言， GNU GLOBAL 都優於 ctags 。&lt;br /&gt;
&lt;br /&gt;
GNU GLOBAL 本身，也提供了 bash 、 tcsh 、 nvi 、 vim 、 less ．．． 的整合。另外 GNU GLOBAL 也提供將程式碼輸出成 HTML 的功能，並產生 hyperlink 。更詳細的功能，請查閱&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.codemud.net/~thinker/GinGin_CGI.py/show_id_doc/247"&gt;http://www.codemud.net/~thinker/GinGin_CGI.py/show_id_doc/247&lt;/a&gt; &lt;br /&gt;
&lt;a href="http://www.gnu.org/software/global/global.html"&gt;http://www.gnu.org/software/global/global.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-2078009961666284464?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/yJFgoEil3Dg" height="1" width="1"/&gt;</content><link rel="related" href="http://heaven.branda.to/~thinker/GinGin_CGI.py/show_id_doc/247" title="GNU GLOBAL 作為分析基礎" /><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/2078009961666284464/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=2078009961666284464" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/2078009961666284464?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/2078009961666284464?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/yJFgoEil3Dg/gnu-global.html" title="GNU GLOBAL 作為分析基礎" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2009/10/gnu-global.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQERnwyfCp7ImA9WhRbEU8.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-5512771826313191395</id><published>2012-02-01T12:15:00.000-08:00</published><updated>2012-02-01T12:15:07.294-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-01T12:15:07.294-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C" /><category scheme="http://www.blogger.com/atom/ns#" term="ToDo" /><title>閱讀 C 和 C++ 原始碼的好幫手</title><content type="html">閱讀 C 和 C++ 原始碼的好幫手&lt;br /&gt;
&lt;br /&gt;
最近有需求讀 C/C++ 的東西, 試了 ctags, cscope 覺得不理想。問了一下收到許多回應 (G+ 、plurk ), 真是太感謝大家了, 減少入門摸索的時間。&lt;br /&gt;
&lt;br /&gt;
試用的感想如下:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;grep&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
優點: 好上手&lt;br /&gt;
缺點: 陽春&lt;br /&gt;
安裝: 內建於 Linux&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;gtags&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
優點: 可找 caller 和 callee&lt;br /&gt;
缺點: 因為索引檔是由 ctags 來的, 會漏東西; 執行方式也有些不便&lt;br /&gt;
安裝: 程式很久沒人更新了, 要做一些修正才裝得起來&lt;br /&gt;
參照官網指示&lt;br /&gt;
make 時看少了什麼 header, 手動補一下 header&lt;br /&gt;
然後 make 還是會失敗, 將 gas.py 的 "import as" 改為 "import asm", 下面用到的模組名也要跟著改, as.py 也要改為 asm.py。python 2.6 後 as 是 keyword&lt;br /&gt;
編好後將幾個用到的 python scripts 第一行由 python2.4 改為 python&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;GNU global&lt;/b&gt;&lt;br /&gt;
GNU GLOBAL - 程式碼分析 - cross reference 的分析工具&lt;br /&gt;
http://gala4th.blogspot.com/2009/10/gnu-global-cross-reference.html&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;ack&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
優點: 比 grep 容易使用, 省得配合一些 command 過濾檔案, 見官網的《Top 10 reasons to use ack instead of grep.》。而且還有彩色的輸出!!&lt;br /&gt;
缺點: 因為沒建 index 的關係, 速度較 id-utils 慢, 我的測試情境要 3s, 而 id-utils 只要 0.006s&lt;br /&gt;
安裝: curl http://betterthangrep.com/ack-standalone &amp;gt; ~/bin/ack &amp;amp;&amp;amp; chmod 0755 !#:3&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;id-utils&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
優點: 速度快, 和測 ack 同樣的情況, 建索引 5.3s, 之後搜尋瞬殺&lt;br /&gt;
缺點: 介面沒有 ack 直覺易用, 我寫了個小程式 gj 以 id-utils 為底, 提供彩色輸出和進一步過濾檔名的功能。&lt;br /&gt;
安裝: Ubuntu 超容易, aptitude install id-utils&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Eclipse CDT&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
優點: 方便開新視窗看 caller、callee&lt;br /&gt;
缺點: 不方便搭 vim 使用 (對 vim 重度使用者才有差); 建 index 有點久, 我的測試情境要數分鐘到十分鐘吧&lt;br /&gt;
安裝: 結果這個是我試最久的, 因為不知怎麼建 index。參考官網 FAQ, 建索引前要先設 include dir path。我一直找不到 context menu, 結果它就是左側的那個專案清單。另外 Eclipse CDT 也會漏一些東西, C++ 特別嚴重。&lt;br /&gt;
結論&lt;br /&gt;
&lt;br /&gt;
用 Eclipes CDT 方便平時快速跳到定義&lt;br /&gt;
輔以 id-utils + gj 確保不會漏東西。之後用一用再視需求來更新 gj 功能。&lt;br /&gt;
2011-12-16 Update&lt;br /&gt;
&lt;br /&gt;
Eclipse CDT 的問題有一部份是我設錯, 詳細設法見用 Eclipse CDT 讀 C/C++ 原始碼&lt;br /&gt;
&lt;br /&gt;
張貼者： fcamel 於 下午11:25&lt;br /&gt;
標籤： C, C++&lt;br /&gt;
10 意見:&lt;br /&gt;
&lt;br /&gt;
Scott TsaiDec 12, 2011 09:30 AM&lt;br /&gt;
以需要能找出全部有用到某函式的地方為前提：&lt;br /&gt;
1. 純粹 C 而不是 C++ 的 code base, cscope + VIM plugin 很好用&lt;br /&gt;
2. Eclipse 與 VIM 見 Vrapper：http://itrs.tw/wiki/IDEs_with_VIM_Emulation&lt;br /&gt;
&lt;br /&gt;
要在 VIM 中方便跳到 search results，我有個奇怪用法：&lt;br /&gt;
1. 將 search result 轉成『grep -n 格式』存在檔案 l 中&lt;br /&gt;
2. vim&lt;br /&gt;
3. :set grepprg=cat\ l&lt;br /&gt;
4. :grep&lt;br /&gt;
5. :copen&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
fcamelDec 12, 2011 10:05 AM&lt;br /&gt;
之前讀 python code 時有用過 pycscope + VIM plugin, 相當不錯, 原以為 cscope + VIM plugin 也可適用, 可惜 C++ 的情況滿多不適用的。&lt;br /&gt;
&lt;br /&gt;
http://vrapper.sourceforge.net/features/&lt;br /&gt;
沒想到 vrapper 有支援 macro, 這樣應該可用, 明天來試試。很久以前用過類似的東西, 但沒有 macro 用起來不順手&lt;br /&gt;
&lt;br /&gt;
最後的例子沒看懂, 是指要先在 cmd line 用 grep -n 將輸出導到檔名 "|" 中, 再做後面的操作嗎??&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
Scott TsaiDec 12, 2011 10:11 AM&lt;br /&gt;
Re: 最後的例子沒看懂&lt;br /&gt;
&lt;br /&gt;
若搜群工具可以輸出 "FILE:LINE:...SNIPPET.." 格式，將結果存於檔案中, 再用以上設定在 VIM 中打開就可以像在 VIM 中用內建 grep 一樣，跳到各搜尋結果。&lt;br /&gt;
&lt;br /&gt;
搜尋工具格式不同，則寫 script 或手動轉。&lt;br /&gt;
VIM 也有 "grepformat" 參數，但我自己是用上述方法。&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
Scott TsaiDec 12, 2011 10:20 AM&lt;br /&gt;
為了主題完整性，跟之後讀者分享 grep 顏色輸出設定：&lt;br /&gt;
&lt;br /&gt;
alias egrep='egrep --color=tty -d skip'&lt;br /&gt;
alias egrpe='egrep --color=tty -d skip'&lt;br /&gt;
alias fgrep='fgrep --color=tty -d skip'&lt;br /&gt;
alias fgrpe='fgrep --color=tty -d skip'&lt;br /&gt;
alias grep='grep --color=tty -d skip'&lt;br /&gt;
alias grpe='grep --color=tty -d skip'&lt;br /&gt;
&lt;br /&gt;
以上可安全的加在 .bashrc 中，&lt;br /&gt;
grep 發現 stdout 不是 tty 時就會改回無顏色控制碼的輸出。&lt;br /&gt;
來源 glibc maintainer Ulrich Drepper:&lt;br /&gt;
http://udrepper.livejournal.com/17109.html&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
小鄭Dec 12, 2011 04:16 PM&lt;br /&gt;
跟ack一樣的功能，不過用Python寫成，程式碼也蠻易讀。&lt;br /&gt;
http://eli.thegreenplace.net/2011/10/14/announcing-pss-a-tool-for-searching-inside-source-code/&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
小迪克/MarkDec 12, 2011 06:55 PM&lt;br /&gt;
Eclipse漏東西是什麼情況? 試試看把indexer的cache limit調大一點...&lt;br /&gt;
By the way, gj還不錯用!! Good Job~XD&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
scwDec 28, 2011 02:32 AM&lt;br /&gt;
還有一個東西叫 lxr, &lt;br /&gt;
http://lxr.sourceforge.net/&lt;br /&gt;
我覺得也滿好用的溜&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
fcamelDec 28, 2011 07:31 AM&lt;br /&gt;
@scw 謝啦, 看起來頗強大的, 明天來試試, 好像是類似 doxygen 的工具?&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
Hello WaylingJan 5, 2012 05:30 PM&lt;br /&gt;
lxr沒顏色~有點難看&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
Scott TsaiJan 5, 2012 05:53 PM&lt;br /&gt;
較新的 lxr 替代品是 dxr:&lt;br /&gt;
http://dxr.mozilla.org/mozilla/index.html&lt;br /&gt;
是以 Clang 為基礎的：&lt;br /&gt;
https://github.com/mozilla/dxr&lt;br /&gt;
&lt;br /&gt;
@fcamel: "lxr 好像是類似 doxygen 的工具?"&lt;br /&gt;
lxr, Linux Cross Reference, 原本是為了研究 Linux Kernel source code 而寫出來的。至今討論 Linux Kernel 內部 API 時還是很常用。&lt;br /&gt;
回覆&lt;br /&gt;
&lt;br /&gt;
===&lt;br /&gt;
大家都怎麼追 C++ 程式碼啊? 試了 gtags, 不過來源就是 ctags, 會漏掉很多東西, cscope 也會, 但單用 grep 太慢, 沒好工具的話, 想說自己硬幹一個基於 grep 的 index 小工具&lt;br /&gt;
&lt;br /&gt;
doxygen or Source Insight&lt;br /&gt;
&lt;br /&gt;
Sid666 說 cscope&lt;br /&gt;
&lt;br /&gt;
Dec 09, 2011 - 04:46PM&lt;br /&gt;
av. visual assist (誤)&lt;br /&gt;
&lt;br /&gt;
York 說 這得視程式碼規模及你打算投入多少時間來決定&lt;br /&gt;
&lt;br /&gt;
York 說 當然，你追這份 code 的原因也要納入考慮&lt;br /&gt;
&lt;br /&gt;
fcamel 說 YorkJong: 我原本指用什麼工具, 的確也如同解決其它問題一樣, 得視情況調整做法&lt;br /&gt;
&lt;br /&gt;
小迪克/SDK 說 eclipse...&lt;br /&gt;
&lt;br /&gt;
Thinker gtags 可以用 regex, 可以 reverse, 可以 grep&lt;br /&gt;
&lt;br /&gt;
Thinker 不是 ctags 可以比擬的..&lt;br /&gt;
&lt;br /&gt;
Thinker 而 cscope 的功能就和 gtags 差不多..&lt;br /&gt;
&lt;br /&gt;
Thinker 如果你只是想加快 grep，建議你用 idutils, 能為所有的 token 建立 index&lt;br /&gt;
&lt;br /&gt;
Thinker 我都是 idutils 和 gtags 合在一起用.. 一些 gtags 沒辨法分析的東西，可以用 idutils 快速改到..&lt;br /&gt;
&lt;br /&gt;
Thinker 我都是 idutils 和 gtags 合在一起用.. 一些 gtags 沒辨法分析的東西，可以用 idutils 快速找到..&lt;br /&gt;
&lt;br /&gt;
Thinker idutils 裡面包括一個叫 gid 的工具，相當於 grep。但 gid 只能針對單一個 token 做 match，而不是一整行。因此，我都是先用 gid 縮小目標，然後把輸出丟給 grep 再做過濾&lt;br /&gt;
&lt;br /&gt;
fcamel 說 Thinker: 謝啦, 之後來試試, 另外在 G+ 有看到 kcwu 推 ack, 看起來也不錯&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
google-gtags&lt;br /&gt;
Server-based tags serving for large codebases. Clients in python and for emacs and vim&lt;br /&gt;
-  Comment  -  Hang out  -  Share&lt;br /&gt;
+3&lt;br /&gt;
15 comments&lt;br /&gt;
&lt;br /&gt;
Shaka Huang  -  好久沒看 C++ 程式碼了.. Orz&lt;br /&gt;
Dec 9, 2011   &lt;br /&gt;
&lt;br /&gt;
Kuang-che Wu  -  只跟 grep 比的話, +ack 不錯. 不過跟你的需求還是差很遠.&lt;br /&gt;
Dec 9, 2011    +2   &lt;br /&gt;
&lt;br /&gt;
Chia Hao Lo  -  +Kuang-che Wu 喔喔, 這東西好用, 該有的不會漏比較重要, 謝啦&lt;br /&gt;
&lt;br /&gt;
btw, 今天才在試 find 的語法, 想少搜一堆不相干的檔案, 但沒找到適合的語法。結果在 ack 的說明裡就看到要怎麼用 find + grep 達到只搜 .cpp 和 .h 的寫法, 原來是 -or 啊&lt;br /&gt;
Dec 9, 2011   &lt;br /&gt;
&lt;br /&gt;
Yu-Teh Shen  -  cscope 的確有時會漏... 我也來試試看ack~&lt;br /&gt;
Dec 9, 2011 (edited)   &lt;br /&gt;
&lt;br /&gt;
Scott Tsai  -  For large C++ code bases I use Eclipse CDT.&lt;br /&gt;
I expect that In a few years, IDEs using libclang based indexers should be pretty sweet as well.&lt;br /&gt;
Dec 11, 2011   &lt;br /&gt;
&lt;br /&gt;
Yu-Teh Shen  -  話說我同事用CDT, 建立index的時候, memory吃到快2g...&lt;br /&gt;
Dec 11, 2011   &lt;br /&gt;
&lt;br /&gt;
Yu-Teh Shen  -  話說 +Scott Tsai 你平常debug是用vimgdb還是用甚饃方式使用gdb? 不會是直接用gdb吧...&lt;br /&gt;
Dec 11, 2011   &lt;br /&gt;
&lt;br /&gt;
Chia Hao Lo  -  +Yu-Teh Shen 現在記憶體超便宜的, 吃 2G ram 不算是問題了&lt;br /&gt;
Dec 11, 2011 (edited)   &lt;br /&gt;
&lt;br /&gt;
Chia Hao Lo  -  +Scott Tsai 之後都來試看看, 那一個用起來最順手 Eclipse CDT, ack, ID Utils&lt;br /&gt;
Dec 11, 2011   &lt;br /&gt;
&lt;br /&gt;
Scott Tsai  -  @Yu Teh Shen: &lt;br /&gt;
1. 最常用的方法真的是『直接用 gdb 』，最有用的指令還是 backtrace&lt;br /&gt;
2. 我後來把 gdb script 語法和 gdb 的 Python API 學了一下。比較複雜的動作寫到 "gdb -x SCRIPT" 裡面 &lt;br /&gt;
3. 有時直接在程式碼中加入 break point: https://github.com/scottt/debugbreak/blob/master/debugbreak.h&lt;br /&gt;
4. 有時切到 gdb-tui: http://davis.lbl.gov/Manuals/GDB/gdb_21.html&lt;br /&gt;
Dec 11, 2011   &lt;br /&gt;
&lt;br /&gt;
Scott Tsai  -  @Yu Teh Shen: re: Eclipse CDT Indexer 用很多記憶體:&lt;br /&gt;
我會改 eclipse.ini 中的 -X ，讓 JVM 一啟動就 alloc 4 G&lt;br /&gt;
&lt;br /&gt;
公司配給你的電腦太爛的話，一邊帶自己的去，一邊『提醒』主管記憶體大一點、有 SSD 的話你每天可以省 15 ~ 60 min 。&lt;br /&gt;
Dec 11, 2011    +1   &lt;br /&gt;
&lt;br /&gt;
Yu-Teh Shen  -  +Scott Tsai 剛剛試了一下gdb -tui, 如果你要編trace code一邊debug, 這樣似乎你可能還是要另外開一個terminal 看code (因為要跳來跳去)?&lt;br /&gt;
Dec 12, 2011 (edited)   &lt;br /&gt;
&lt;br /&gt;
Scott Tsai  -  +Yu Ten Shen: 基本上對。詳細一點說：&lt;br /&gt;
我開發 C/C++ 程式的方法，刻意避開了『很依賴 debugger』的風格。&lt;br /&gt;
&lt;br /&gt;
多數會先擬好除錯計畫，在 code base 中插入好檢查、pretty print 資料結構的程式才開始。在除錯時，不只是另外開 editor 看 code，同時還有除錯計畫的筆記，紀錄如『我懷疑哪些資料有壞掉』，『已經作過哪些實驗』、『目前看到的 corruption 在 stack 還是 heap 上 address 某某附近』等。&lt;br /&gt;
&lt;br /&gt;
除錯到一半，覺得問題不容易解時，我也會先 trace code 把局部的 data flow 與 control flow 寫在筆記裡面才繼續開始除錯，避免要『跳來跳去』看 code。&lt;br /&gt;
&lt;br /&gt;
在處理複雜的 code base 或長時間執行的系統軟體時，上述風格頗有道理 -- 最重要的是逼自己先分析問題，而不是先開始單步執行然後見樹不見林。如concurrency 的問題不適合用 debugger 觀察、最佳化編譯的 release build 中，你要看的變數原本已經沒用到的話，暫存器已被拿來存別的值了。&lt;br /&gt;
&lt;br /&gt;
我也同意有經驗的 developer 看較簡單 code base 時，直接在 debugger 邊跑邊讀 code 可能比較快。最極端的如大學『C 程式語言入門』助教改作業。但我在工研社教了多屆 C 入門，也是除了分析 core dump 以外，不用 debugger 的。因為學生人數少，看他們的 code 可以教的更深入。&lt;br /&gt;
&lt;br /&gt;
也有遇過很需要 debugger 的時候：編譯或連結時間很長的 C++ code base 要改 code 追特定問題成本太高 (header only style 的 C++ 配上 binutils 中舊的、非 gold 的那版 linker 就很慘了）。我會盡量將 break point, watch point, 檢查與dump 資料結構的動作寫成 gdb script 或從 Python 用 gdb API，避免在 debugger 中重複同樣操作。&lt;br /&gt;
&lt;br /&gt;
結論：&lt;br /&gt;
我同意直接用命令列的 gdb 比起用整合在 IDE 中的除錯界面，開發者要多記住很多資訊，有時感覺起來像多餘負擔。最後，整合 gdb 的 IDE 中，Eclipse CDT 與 QtCreator 是支援 remote debugging （包含 cross debugging）且有好的團隊在維護的；但我平常還是覺得從命令列用 gdb 比較快。&lt;br /&gt;
Dec 12, 2011 (edited)    +6   &lt;br /&gt;
&lt;br /&gt;
Chia Hao Lo  -  可惜 +1 只能按一次啊~~&lt;br /&gt;
Dec 12, 2011    &lt;br /&gt;
&lt;br /&gt;
Yu-Teh Shen  -  +Scott Tsai 感謝你的分享, 我來我的wiki上面開個scott 專區好了~&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://fcamel-life.blogspot.com/2011/12/cc.html"&gt;http://fcamel-life.blogspot.com/2011/12/cc.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://plus.google.com/111353793049965752735/posts/GAVtr4HXXc4"&gt;https://plus.google.com/111353793049965752735/posts/GAVtr4HXXc4&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.plurk.com/p/eyqy5v"&gt;http://www.plurk.com/p/eyqy5v&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-5512771826313191395?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/kr3vgG4C2OI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/5512771826313191395/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=5512771826313191395" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5512771826313191395?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5512771826313191395?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/kr3vgG4C2OI/c-c.html" title="閱讀 C 和 C++ 原始碼的好幫手" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/02/c-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4CQ3g4fip7ImA9WhRbEU8.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-7670933721158314549</id><published>2012-02-01T12:09:00.000-08:00</published><updated>2012-02-01T12:09:22.636-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-01T12:09:22.636-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tools" /><category scheme="http://www.blogger.com/atom/ns#" term="ToDo" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><title>GNU GLOBAL - 程式碼分析 - cross reference 的分析工具</title><content type="html">GNU GLOBAL - 程式碼分析 - cross reference 的分析工具&lt;br /&gt;
by thinker&lt;br /&gt;
2 Columns&lt;br /&gt;
關鍵字:&lt;br /&gt;
程式碼分析&lt;br /&gt;
GNU GLOBAL 是類似於 ctags 的工具，用以建立 source code 符號定義位置的 database 。除了符號定義之外，global 還建立符號 xref (cross reference) 的 database ，用以快速查詢 xref 的位置，是個很方便的設計。&lt;br /&gt;
&lt;br /&gt;
查詢 xref 位置的功能，讓使用者能很快的得知何處使用某個指定的符號，可用以確定符號名稱更改時，是否有漏網之魚。或者，也可透過 xref ，以了解符號在系統中的作用、角色。&lt;br /&gt;
&lt;br /&gt;
除了建立 tag 和 xref database 之外， global 提供將程式碼轉成 HTML ，並依 xref 產生 link 的能力。然而，這方面的功能， doxygen 應該更為成熟，輸出的結果也更為美觀。&lt;br /&gt;
&lt;br /&gt;
除此， global 還提供 vim 、 nvi 、 emacs 甚至是 bash 和 less 的查詢介面。透過 editor 查詢的功能就不用說了，和 bash 整合，提供簡短的指令，能快速的查詢、瀏灠程式碼。例如:&lt;br /&gt;
&lt;br /&gt;
[/usr/src/sys] x main&lt;br /&gt;
&amp;gt;    1  main              70 alpha/alpha/gensetdefs.c main(in&lt;br /&gt;
2  main             1500 alpha/alpha/ieee_float.c main(i&lt;br /&gt;
3  main             227 boot/alpha/boot1/boot1.c main()&lt;br /&gt;
[/usr/src/sys] show 3&lt;br /&gt;
(Load editor and show boot/alpha/boot1/boot1.c at line 227.)&lt;br /&gt;
&lt;br /&gt;
這個範例是在 bash 下，查詢有哪些位置定義了 main function ，查詢的結果列出了三個 main function 。接著 show 第三個 main function 的內容，也就是執行 editor (vi 或其它) 顯示該段程式碼。除此之外，還提供 bash 下的 bookmark 等等的功能。&lt;br /&gt;
&lt;br /&gt;
至於 less 的整合，也提供了一些有趣的功能。例如:&lt;br /&gt;
&lt;br /&gt;
$ less -t main&lt;br /&gt;
main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
int i;&lt;br /&gt;
.....&lt;br /&gt;
[xxx/main.c (tag 1 of 55)]&lt;br /&gt;
&lt;br /&gt;
執行 less 以顯示 main function 的內容。&lt;br /&gt;
&lt;br /&gt;
我之所以介紹 GNU GLOBAL ，是因為我在最近的程式碼分析研究當中，以 global 為基礎，對程式碼的 cross reference 進行分析。分析的結果，能幫助我們了解 module 在系統中的作用和關聯性。這對經常在看別人程式碼的 open source 的 programmer 非常的重要，在不確定 module 的關聯性時， programmer 往往是處於傍偟和猶豫當中，遲遲不敢動手。 cross reference 的分析工具，讓 programmer 快速掌握 module ，減少猶豫的尷尬階段。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://heaven.branda.to/~thinker/GinGin_CGI.py/show_id_doc/258"&gt;http://heaven.branda.to/~thinker/GinGin_CGI.py/show_id_doc/258&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-7670933721158314549?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/Hf9BtYHBUOk" height="1" width="1"/&gt;</content><link rel="related" href="http://heaven.branda.to/~thinker/GinGin_CGI.py/show_id_doc/258" title="GNU GLOBAL - 程式碼分析 - cross reference 的分析工具" /><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/7670933721158314549/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=7670933721158314549" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/7670933721158314549?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/7670933721158314549?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/Hf9BtYHBUOk/gnu-global-cross-reference.html" title="GNU GLOBAL - 程式碼分析 - cross reference 的分析工具" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2009/10/gnu-global-cross-reference.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UHRX4yfCp7ImA9WhRbEE4.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-716992176323445951</id><published>2012-01-31T11:47:00.000-08:00</published><updated>2012-01-31T11:47:14.094-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-31T11:47:14.094-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="vim" /><title>Use grep to search a string in files recursively and store the grep results in a quickfix window</title><content type="html">Use grep to search a string in files recursively and store the grep results in a quickfix window&lt;br /&gt;
&lt;pre&gt;:grep -r 'pattern' . --include '*.c'

:copen             " open the quickfix window
:cw                " open the quickfix window if there are entries (so if your grep has no results, it won't appear).

&amp;lt;ENTER&amp;gt;            " Open the line of a file in a new buffer.
Ctrl-W &amp;lt;ENTER&amp;gt;     " Open the file/line in a new window.
:.cc               " Open the line of a file in a new buffer.

:cfile debug.txt   " read the content in debug.txt to a quickfix window.
                   " Note: follow this format: "filename:line number:error message"

:cgetfile debug.txt " Just like "cfile" but don't jump to the first entry.

:cclose            " close the quickfix window.
:quit              " close the quickfix window.
&lt;/pre&gt;&lt;br /&gt;
Edit ~/.vimrc:&lt;br /&gt;
" open quickfix window automatically after running grep command.&lt;br /&gt;
command! -nargs=+ Mygrep execute "silent grep! &amp;lt;args&amp;gt;" | copen&lt;br /&gt;
&lt;br /&gt;
:Mygrep -r 'pattern' . --include '*.c'&lt;br /&gt;
&lt;br /&gt;
Performing a customized grep search on the word under the cursor:&lt;br /&gt;
map &amp;lt;F4&amp;gt; :execute " grep -srnw --binary-files=without-match --exclude-dir=.git --exclude-from=exclude.list . -e " . expand("&amp;lt;cword&amp;gt;") . " " &amp;lt;bar&amp;gt; cwindow&amp;lt;CR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:help grep&lt;br /&gt;
:help copen&lt;br /&gt;
:help quickfix&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/1234394/selecting-resulting-files-from-grep-in-vim"&gt;http://stackoverflow.com/questions/1234394/selecting-resulting-files-from-grep-in-vim&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/6373293/vim-how-to-store-the-grep-results-in-a-buffer"&gt;http://stackoverflow.com/questions/6373293/vim-how-to-store-the-grep-results-in-a-buffer&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://vim.wikia.com/wiki/Find_in_files_within_Vim"&gt;http://vim.wikia.com/wiki/Find_in_files_within_Vim&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-716992176323445951?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/AkIJixnfrBs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/716992176323445951/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=716992176323445951" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/716992176323445951?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/716992176323445951?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/AkIJixnfrBs/use-grep-to-search-string-in-files.html" title="Use grep to search a string in files recursively and store the grep results in a quickfix window" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/use-grep-to-search-string-in-files.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUCRng4eSp7ImA9WhRbEE4.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-5226093239336777902</id><published>2012-01-31T09:51:00.000-08:00</published><updated>2012-01-31T09:51:07.631-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-31T09:51:07.631-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="command" /><title>grep searchs a string in filename wildcards recursively</title><content type="html">To search all files under /dir for "blah", run the following:&lt;br /&gt;
&lt;br /&gt;
# grep -r blah /dir&lt;br /&gt;
&lt;br /&gt;
You can not use wildards directly in this manner, for example, the following will not search all text files:&lt;br /&gt;
&lt;br /&gt;
# grep -r blah *.txt&lt;br /&gt;
&lt;br /&gt;
This doesn't work because the wildcard is expanded by the shell before grep is called. Instead, search the current directory (or whichever one you want) and pass the --include option:&lt;br /&gt;
&lt;br /&gt;
# grep -r blah . --include "*.txt"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://mindspill.net/computing/linux-notes/recursive-grep-and-filename-wildcards/"&gt;http://mindspill.net/computing/linux-notes/recursive-grep-and-filename-wildcards/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-5226093239336777902?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/AiErJmMK1Xg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/5226093239336777902/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=5226093239336777902" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5226093239336777902?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5226093239336777902?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/AiErJmMK1Xg/grep-searchs-string-in-filename.html" title="grep searchs a string in filename wildcards recursively" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/grep-searchs-string-in-filename.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUBQns4fSp7ImA9WhRbEE4.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-663028464249890460</id><published>2012-01-31T09:50:00.001-08:00</published><updated>2012-01-31T09:50:53.535-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-31T09:50:53.535-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><title>Debugging load library path issues</title><content type="html">Debugging load library path issues&lt;br /&gt;
If you get a problem with a library that can't find another, you should check the library's dependencies and make sure that the directory in which the missing library resides is part of the load library path.&lt;br /&gt;
&lt;br /&gt;
One example of this problem, that I experienced recently, occurred when the Magick.so library was unable to open the libMagick.so.10 library. The error message was as follows:&lt;br /&gt;
&lt;br /&gt;
Can't load '/usr/lib/perl5/site_perl/5.8.7/i686-linux/auto/Image/Magick/Magick.so' for module Image::Magick: libMagick.so.10: cannot open shared object file: No such file or directory at /usr/lib/perl5/5.8.7/i686-linux/DynaLoader.pm line 230. at (eval 113) line 1 Compilation failed in require at (eval 113) line 1. BEGIN failed--compilation aborted at (eval 113) line 1.&lt;br /&gt;
Find out library dependencies with ldd&lt;br /&gt;
&lt;br /&gt;
The ldd command will check the dependencies of a library.&lt;br /&gt;
&lt;br /&gt;
ldd /the/library/path/libWhatever.so&lt;br /&gt;
Using the above example problem:&lt;br /&gt;
&lt;br /&gt;
username@localhost [~]# ldd /usr/lib/perl5/site_perl/5.8.7/i686-linux/auto/Image/Magick/Magick.so&lt;br /&gt;
libMagick.so.10 =&gt; not found&lt;br /&gt;
libfreetype.so.6 =&gt; /usr/lib/libfreetype.so.6 (0x0099a000)&lt;br /&gt;
libz.so.1 =&gt; /usr/lib/libz.so.1 (0x00111000)&lt;br /&gt;
libtiff.so.3 =&gt; /usr/lib/libtiff.so.3 (0x00121000)&lt;br /&gt;
libjpeg.so.62 =&gt; /usr/lib/libjpeg.so.62 (0x00d54000)&lt;br /&gt;
libXext.so.6 =&gt; /usr/X11R6/lib/libXext.so.6 (0x001f4000)&lt;br /&gt;
libSM.so.6 =&gt; /usr/X11R6/lib/libSM.so.6 (0x0016e000)&lt;br /&gt;
libICE.so.6 =&gt; /usr/X11R6/lib/libICE.so.6 (0x00910000)&lt;br /&gt;
libX11.so.6 =&gt; /usr/X11R6/lib/libX11.so.6 (0x0039d000)&lt;br /&gt;
libXt.so.6 =&gt; /usr/X11R6/lib/libXt.so.6 (0x005bc000)&lt;br /&gt;
libpthread.so.0 =&gt; /lib/tls/libpthread.so.0 (0x004cc000)&lt;br /&gt;
libm.so.6 =&gt; /lib/tls/libm.so.6 (0x00216000)&lt;br /&gt;
libc.so.6 =&gt; /lib/tls/libc.so.6 (0x00bda000)&lt;br /&gt;
libdl.so.2 =&gt; /lib/libdl.so.2 (0x00177000)&lt;br /&gt;
/lib/ld-linux.so.2 (0x002c2000)&lt;br /&gt;
You can see in that the libMagick.so.10 library was not found.&lt;br /&gt;
&lt;br /&gt;
Locate the library with find or locate or slocate or by any other means&lt;br /&gt;
&lt;br /&gt;
Find the location of the library that couldn't be found by ldd. The chances are that the library will be in a subdirectory of /usr. Continuing with the above example...&lt;br /&gt;
&lt;br /&gt;
username@localhost [~]# find /usr -name "libMagick.so.10"&lt;br /&gt;
/usr/local/lib/libMagick.so.10&lt;br /&gt;
Add the library to the load library path with ldconfig&lt;br /&gt;
&lt;br /&gt;
In the words of the man page, ldconfig will configure dynamic linker run time bindings. Add your missing library to the bindings with the following command:&lt;br /&gt;
&lt;br /&gt;
ldconfig /path/to/add&lt;br /&gt;
For our libMagick example, this would be:&lt;br /&gt;
&lt;br /&gt;
username@localhost [~]# ldconfig /usr/local/lib&lt;br /&gt;
You can see a list of librarys that are being used with the -p flag.&lt;br /&gt;
&lt;br /&gt;
username@localhost [~]# ldconfig -p&lt;br /&gt;
907 libs found in cache `/etc/ld.so.cache'&lt;br /&gt;
libzvt.so.2 (libc6) =&gt; /usr/lib/libzvt.so.2&lt;br /&gt;
libzvt.so (libc6) =&gt; /usr/lib/libzvt.so&lt;br /&gt;
libzip.so (libc6, hwcap: 0x0001000000000000) =&gt; /opt/blackdown-jdk-1.4.2.03/jre/lib/i386/libzip.so&lt;br /&gt;
libz.so.1 (libc6) =&gt; /lib/libz.so.1&lt;br /&gt;
libz.so (libc6) =&gt; /lib/libz.so&lt;br /&gt;
libxslt.so.1 (libc6) =&gt; /usr/lib/libxslt.so.1&lt;br /&gt;
libxslt.so (libc6) =&gt; /usr/lib/libxslt.so&lt;br /&gt;
[...cut...]&lt;br /&gt;
If you want to make make the changes more permanent, so that you don't have to remember to specify the directory next time you run the command, you can add it to the /etc/ld.so.conf file, though different linux distributions manage this file in different ways.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://mindspill.net/computing/linux-notes/debugging-load-library-path-issues/"&gt;http://mindspill.net/computing/linux-notes/debugging-load-library-path-issues/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-663028464249890460?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/tdxW07GpEYQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/663028464249890460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=663028464249890460" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/663028464249890460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/663028464249890460?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/tdxW07GpEYQ/debugging-load-library-path-issues.html" title="Debugging load library path issues" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/debugging-load-library-path-issues.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EFR3g4eyp7ImA9WhRUGUg.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-1567258253389842881</id><published>2012-01-30T12:33:00.000-08:00</published><updated>2012-01-30T12:33:36.633-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T12:33:36.633-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><title>FreeBSD - Backup and restore FreeBSD using Fixit CD</title><content type="html">Since FreeSBIE have not been updated since year 2007, its kernel recognizing new hardware starts to worry me as it is based on FreeBSD 6.2 and it is going to reach EoL (end of life) by end of this year, 2010. Is time to experiment on new way restoring backup.&lt;br /&gt;
&lt;br /&gt;
The FreeBSD installation process does mentioned about "Fixit" CD booting. After meddling around with it, it's actually referring to another bootable CD which its label name consits of "livefs" (Live File System). It's also known as "disk 2" prior to FreeBSD 7.&lt;br /&gt;
e.g.&lt;br /&gt;
Installation disc -- &gt; 8.0-RELEASE-i386-disc1.iso&lt;br /&gt;
Live File systems disc --&gt; 8.0-RELEASE-i386-livefs.iso&lt;br /&gt;
&lt;br /&gt;
Do take note that the dump/restore instruction from the previous post "Freebsd – Backup &amp; restore for disaster recovery" is still valid. This post is served as a "update" as it won't be using FreeSBIE, rather, it will using the livefs to start the restoration of the partition(s).&lt;br /&gt;
&lt;br /&gt;
Without further ado, here's the instruction :&lt;br /&gt;
&lt;br /&gt;
A quick note, after experimenting with a few backup compress method, below are the summary of my findings :&lt;br /&gt;
dump and compress using bzip2 (not so good as bzip is the slowest)&lt;br /&gt;
dump -0auLf - /dev/ad0s1a | bzip2 &gt; root_partition.bzip2&lt;br /&gt;
dump and compress using gzip (good choice as gzip perform faster than bzip2 and the compression is fairly good)&lt;br /&gt;
dump -0auLf - /dev/ad0s1a | gzip &gt; root_partition.gzip&lt;br /&gt;
plain dump without compression (fast if target disk can write fast enough)&lt;br /&gt;
dump -0auLf root_partition.dump /dev/ad0s1a&lt;br /&gt;
&lt;br /&gt;
My preferred compress method will be using gzip as it's compression ratio is good with fair compressing time taken. In this case, the backup of the partition(s) is done with the command :&lt;br /&gt;
dump -0auLf - /dev/ad0s1a | gzip &gt; root_partition.gzip&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is the updated version of how to use Live File System CD to start the restoration process :&lt;br /&gt;
Partition &amp; Label the disks&lt;br /&gt;
Boot the Installation disc (disc 1)&lt;br /&gt;
At the "sysinstall Main Menu", go to "Configure --&gt; Fdisk" and perform the following :&lt;br /&gt;
Partition the disk as desire.&lt;br /&gt;
Next, type "w" to write changes to disk.&lt;br /&gt;
BEWARE:this step will wipe all the contents of the hard disk.&lt;br /&gt;
Choose "Label" to label the partitions created in the previous step. Perform the following (similar to previous steps) :&lt;br /&gt;
Label the partition as desire.&lt;br /&gt;
After labeling the partition, note down the partition label. e.g.&lt;br /&gt;
ad0s1a --&gt; "/" or root partition&lt;br /&gt;
&lt;br /&gt;
ad0s2b --&gt; swap partition&lt;br /&gt;
Move the up/down keys to highlight the "Disk:" and NOT the partition ("ad0s1a").&lt;br /&gt;
Next, type "w" to write changes to disk.&lt;br /&gt;
Start the Fixit CD&lt;br /&gt;
At the main menu, go to "Fixit --&gt; CDROM/DVD"&lt;br /&gt;
At the message "Please insert a FreeBSD live filesystem CD/DVD and press return" message, change the installation disc in the drive to Livefs disc (aka disc2).&lt;br /&gt;
Then press enter to continue.&lt;br /&gt;
Restore the backup&lt;br /&gt;
Use the command "mount" to confirm the partitions are mounted accordingly. "/" or root partition should be mounted as /mnt&lt;br /&gt;
Create the external mount point &amp; temporary directory. In this scenario, the backup file is stored in a FAT32 formatted USB external hard disk. The temporary directory is for later use with gzip command.&lt;br /&gt;
mkdir /tmp/usb /mnt/writable_tmp&lt;br /&gt;
Mount the external USB hard disk :&lt;br /&gt;
mount_msdosfs /dev/da0s1 /tmp/usb&lt;br /&gt;
&lt;br /&gt;
*** using the usual command to mount USB hard disk "mount -t msdosfs /dev/da0s1 /tmp/usb" will get an error. See below caveats.&lt;br /&gt;
The temporary directory environment variable originally points to a read only directory. This result in "restore" command complaining about having not enough disk space to restore.&lt;br /&gt;
Re-point it to a writable disk, use the below command :&lt;br /&gt;
export TMPDIR=/tmp/writable_tmp/&lt;br /&gt;
Start the restoration process :&lt;br /&gt;
cd  /mnt&lt;br /&gt;
gzcat /tmp/usb/root_partition.gzip | restore -rvf -&lt;br /&gt;
Repeat the previous step for the rest of the partitions until all partitions are restored.&lt;br /&gt;
&lt;br /&gt;
CAVEATS :&lt;br /&gt;
When executing the command :&lt;br /&gt;
mount -t msdosfs /dev/da0s1 /tmp/usb&lt;br /&gt;
&lt;br /&gt;
An error return :&lt;br /&gt;
mount: exec mount_msdosfs not found in /sbin:/usr/sbin: No such file or directory&lt;br /&gt;
&lt;br /&gt;
For some reason, mount_msdosfs is in /mnt2/sbin/ but "mount" cannot find it.&lt;br /&gt;
Solution 1 :&lt;br /&gt;
Replace the "mount" command with equivalent "mount_msdosfs". Execute it without the need to specify parameter "-t msdosfs"&lt;br /&gt;
e.g.&lt;br /&gt;
mount_msdosfs /dev/da0s1 /tmp/usb&lt;br /&gt;
&lt;br /&gt;
Solution 2&lt;br /&gt;
Soft link the command "mount_msdosfs" to the same directory where mount resides :&lt;br /&gt;
cd /sbin;ln -s /mnt2/sbin/mount_msdosfs mount_msdosfs&lt;br /&gt;
&lt;br /&gt;
then mount it again with the usual command.&lt;br /&gt;
&lt;br /&gt;
Nemaste !!!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://scratching.psybermonkey.net/2010/01/freebsd-backup-and-restore-freebsd.html"&gt;http://scratching.psybermonkey.net/2010/01/freebsd-backup-and-restore-freebsd.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-1567258253389842881?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/Xs5HSgd1UrA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/1567258253389842881/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=1567258253389842881" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/1567258253389842881?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/1567258253389842881?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/Xs5HSgd1UrA/freebsd-backup-and-restore-freebsd.html" title="FreeBSD - Backup and restore FreeBSD using Fixit CD" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/freebsd-backup-and-restore-freebsd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04DRHk5cCp7ImA9WhRUGUk.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-5759576221175162190</id><published>2012-01-30T10:59:00.001-08:00</published><updated>2012-01-30T10:59:35.728-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T10:59:35.728-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><category scheme="http://www.blogger.com/atom/ns#" term="Nginx" /><title>Install Nginx, PHP-FPM and Varnish on FreeBSD 8.2</title><content type="html">Install Nginx, PHP-FPM and Varnish on FreeBSD 8.2&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/www/nginx&lt;br /&gt;
&lt;br /&gt;
# make install clean&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; make sure you select important option such as:&lt;br /&gt;
HTTP_REWRITE_MODULE=on&lt;br /&gt;
HTTP_SSL_MODULE=on&lt;br /&gt;
&lt;br /&gt;
and others as per your requirements.&lt;br /&gt;
&lt;br /&gt;
# echo '### Nginx' &amp;lt;&amp;lt; /etc/rc.conf&lt;br /&gt;
# echo 'nginx_enable="YES"' &amp;lt;&amp;lt; /etc/rc.conf&lt;br /&gt;
&lt;br /&gt;
# vim /usr/local/etc/nginx/nginx.conf&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;gzip on;
    gzip_min_length 1000;
    gzip_proxied expired no-cache no-store private auth;
    gzip_disable "MSIE [1-6]\.";
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    server {
            server_name mydomain1.com mydomain2.com mydomain3.com;
            root /usr/local/www/nginx/drupal7; ## &amp;lt;-- Your only path reference.

            client_max_body_size 20M; # Maximum allowed size for uploaded files

            location = /favicon.ico {
                    log_not_found off;
                    access_log off;
            }

            location = /robots.txt {
                    allow all;
                    log_not_found off;
                    access_log off;
            }

            # This matters if you use drush
            location = /backup {
                    deny all;
            }

            # Very rarely should these ever be accessed outside of your lan
            location ~* \.(txt|log)$ {
                    allow 192.168.0.0/16;
                    deny all;
            }

            location ~ \..*/.*\.php$ {
                    return 403;
            }

            location / {
                    # This is cool because no php is touched for static content
                    try_files $uri @rewrite;
            }

            location @rewrite {
                    # Some modules enforce no slash (/) at the end of the URL
                    # Else this rewrite block wouldn't be needed (GlobalRedirect)
                    rewrite ^/(.*)$ /index.php?q=$1;
            }

            location ~ \.php$ {
                    fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    ### NOTE: You should have "cgi.fix_pathinfo = 0" in php.ini
                    include fastcgi_params;
                    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                    fastcgi_intercept_errors on;
      #fastcgi_pass 127.0.0.1:9000;  #pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
                    fastcgi_pass unix:/tmp/php-fpm.sock;
            }

            ### disable PHP execution on upload attachement directory
            location /sites/default/files/ {
              location ~ .*\.(php)?$
              {
                 deny all;
              }
            }

            # Fighting with ImageCache? This little gem is amazing.
            location ~ ^/sites/.*/files/imagecache/ {
                    try_files $uri @rewrite;
            }
            # Catch image styles for D7 too.
            location ~ ^/sites/.*/files/styles/ {
                    try_files $uri @rewrite;
            }

            location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                    expires max;
                    log_not_found off;
            }

            # nginx status
            location /NginxStatus {
              stub_status on;
              access_log on;
              auth_basic NginxStatus;
              auth_basic_user_file conf/htpasswd;
            }
    }
&lt;/pre&gt;&lt;br /&gt;
# /usr/local/etc/rc.d/nginx start&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Change this line for nginx:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# vim /usr/local/etc/php.ini&lt;br /&gt;
cgi.fix_pathinfo = 0&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install php and php-fpm:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
// For PHP5.3&lt;br /&gt;
# cd /usr/ports/lang/php5 ; make install&lt;br /&gt;
&lt;br /&gt;
// For PHP5.2&lt;br /&gt;
# cd /usr/ports/lang/php52 ; make install&lt;br /&gt;
&lt;br /&gt;
===&amp;lt; The following configuration options are available for php5-5.3.8:&lt;br /&gt;
CLI=on "Build CLI version"&lt;br /&gt;
CGI=on "Build CGI version"&lt;br /&gt;
FPM=on "Build FPM version (experimental)"&lt;br /&gt;
APACHE=off "Build Apache module"&lt;br /&gt;
AP2FILTER=off " Use Apache 2.x filter interface (experimental)"&lt;br /&gt;
DEBUG=off "Enable debug"&lt;br /&gt;
SUHOSIN=on "Enable Suhosin protection system"&lt;br /&gt;
MULTIBYTE=on "Enable zend multibyte support"&lt;br /&gt;
IPV6=off "Enable ipv6 support"&lt;br /&gt;
MAILHEAD=on "Enable mail header patch"&lt;br /&gt;
LINKTHR=on "Link thread lib (for threaded extensions)"&lt;br /&gt;
===&amp;lt; Use 'make config' to modify these settings&lt;br /&gt;
&lt;br /&gt;
// For PHP5.3&lt;br /&gt;
# cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini&lt;br /&gt;
&lt;br /&gt;
// For PHP5.2&lt;br /&gt;
# cp /usr/local/etc/php.ini-recommended /usr/local/etc/php.ini&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install PHP Extensions&lt;/b&gt;&lt;br /&gt;
// For PHP5.3&lt;br /&gt;
# cd /usr/ports/lang/php5-extensions ; make install&lt;br /&gt;
&lt;br /&gt;
// For PHP5.2&lt;br /&gt;
# cd /usr/ports/lang/php52-extensions ; make install&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit php-fpm.conf:&lt;/b&gt;&lt;br /&gt;
# vim /usr/local/etc/php-fpm.conf&lt;br /&gt;
; comment out following line and add the line below.&lt;br /&gt;
;listen = 127.0.0.1:9000&lt;br /&gt;
listen = /tmp/php-fpm.sock&lt;br /&gt;
&lt;br /&gt;
request_terminate_timeout=30s&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit rc.conf&lt;/b&gt;&lt;br /&gt;
# vim /etc/rc.conf&lt;br /&gt;
### php-fpm&lt;br /&gt;
php_fpm_enable="YES"&lt;br /&gt;
&lt;br /&gt;
Change this line for nginx&lt;br /&gt;
&lt;br /&gt;
# vim /usr/local/etc/php.ini&lt;br /&gt;
&lt;br /&gt;
date.timezone = America/Vancouver&lt;br /&gt;
magic_quotes_gpc = Off&lt;br /&gt;
max_execution_time = 120&lt;br /&gt;
max_input_time = 60&lt;br /&gt;
memory_limit = 256M&lt;br /&gt;
upload_max_filesize = 20M&lt;br /&gt;
post_max_size = 30M&lt;br /&gt;
cgi.fix_pathinfo = 0&lt;br /&gt;
log_errors = On&lt;br /&gt;
error_log = /var/log/php_err.log&lt;br /&gt;
&lt;br /&gt;
# touch /var/log/php_err.log&lt;br /&gt;
# chown www:www /var/log/php_err.log&lt;br /&gt;
# chmod 660 /var/log/php_err.log&lt;br /&gt;
&lt;br /&gt;
# /usr/local/etc/rc.d/php-fpm start&lt;br /&gt;
# /usr/local/etc/rc.d/nginx restart&lt;br /&gt;
&lt;br /&gt;
# tail /var/log/nginx-error.log&lt;br /&gt;
&lt;br /&gt;
# tail /var/log/php-fpm.log&lt;br /&gt;
&lt;br /&gt;
# tail /var/log/messages&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rotate Nginx and PHP log files:&lt;/b&gt;&lt;br /&gt;
# vim /etc/newsyslog.conf&lt;br /&gt;
/var/log/nginx-access.log                               600  7     100000       *     JC    /var/run/nginx.pid&lt;br /&gt;
/var/log/nginx-error.log                                600  7     100000       *     JC    /var/run/nginx.pid&lt;br /&gt;
/var/log/php-fpm.log                            600  7     100000       *     JC    /var/run/php-fpm.pid&lt;br /&gt;
/var/log/php_errors.log                         600  7     100000       *     JC&lt;br /&gt;
&lt;br /&gt;
# /etc/rc.d/newsyslog restart&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install Varnish&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/www/varnish ; make install clean&lt;br /&gt;
&lt;br /&gt;
Reconfigure your web server to listen on localhost:8080&lt;br /&gt;
&lt;br /&gt;
# echo 'varnishd_enable="YES"' &amp;lt;&amp;lt; /etc/rc.conf&lt;br /&gt;
# echo 'varnishd_flags="-s malloc,1G -a 127.0.0.1:80 -b 127.0.0.1:8080"' &amp;lt;&amp;lt; /etc/rc.conf&lt;br /&gt;
# echo 'varnishlog_enable="YES"' &amp;lt;&amp;lt; /etc/rc.conf&lt;br /&gt;
&lt;br /&gt;
# /usr/local/etc/rc.d/varnishd start&lt;br /&gt;
&lt;br /&gt;
# /usr/local/etc/rc.d/varnishncsa onestart&lt;br /&gt;
&lt;br /&gt;
# tail /var/log/varnishncsa.log&lt;br /&gt;
&lt;br /&gt;
# /usr/local/bin/varnishtest&lt;br /&gt;
&lt;br /&gt;
# /usr/local/bin/varnishstat&lt;br /&gt;
&lt;br /&gt;
# ls -lh /usr/local/varnish/`hostname`&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install webbench&lt;/b&gt;&lt;br /&gt;
# cd /usr/ports/benchmarks/webbench ; make install clean&lt;br /&gt;
&lt;br /&gt;
# webbench -c 3000 -t 60 http://test.local/index.php&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
Install Nginx, PHP-FPM and Varnish on FreeBSD 8.2&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2012/01/install-nginx-php-fpm-and-varnish-on.html"&gt;http://gala4th.blogspot.com/2012/01/install-nginx-php-fpm-and-varnish-on.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Apache MPM Worker + mod_fastcgi + PHP-FPM&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/07/apache-mpm-worker-modfastcgi-php-fpm.html"&gt;http://gala4th.blogspot.com/2011/07/apache-mpm-worker-modfastcgi-php-fpm.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Web Performance Tuning Tips Solutions for Drupal Sites&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/12/web-performance-tuning-tips-solutions.html"&gt;http://gala4th.blogspot.com/2010/12/web-performance-tuning-tips-solutions.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Running Drupal with Nginx&lt;br /&gt;
&lt;a href="http://wiki.nginx.org/Drupal"&gt;http://wiki.nginx.org/Drupal&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
high performance caching reverse proxy: Varnish (安裝架設篇)&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/12/high-performance-caching-reverse-proxy.html"&gt;http://gala4th.blogspot.com/2010/12/high-performance-caching-reverse-proxy.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
[FreeBSD &amp;amp; Linux]網站分流：簡易架設 HAProxy 伺服器&lt;br /&gt;
&lt;a href="http://blog.wu-boy.com/2008/06/freebsd-linux%E7%B6%B2%E7%AB%99%E5%88%86%E6%B5%81%EF%BC%9A%E7%B0%A1%E6%98%93%E6%9E%B6%E8%A8%AD-haproxy-%E4%BC%BA%E6%9C%8D%E5%99%A8/"&gt;http://blog.wu-boy.com/2008/06/freebsd-linux%E7%B6%B2%E7%AB%99%E5%88%86%E6%B5%81%EF%BC%9A%E7%B0%A1%E6%98%93%E6%9E%B6%E8%A8%AD-haproxy-%E4%BC%BA%E6%9C%8D%E5%99%A8/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Scaling Rails Site：Reading Material # 1&lt;br /&gt;
&lt;a href="http://wp.xdite.net/?p=1597"&gt;http://wp.xdite.net/?p=1597&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-5759576221175162190?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/qYEhpLV0bRE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/5759576221175162190/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=5759576221175162190" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5759576221175162190?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5759576221175162190?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/qYEhpLV0bRE/install-nginx-php-fpm-and-varnish-on.html" title="Install Nginx, PHP-FPM and Varnish on FreeBSD 8.2" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/install-nginx-php-fpm-and-varnish-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04BSX49eyp7ImA9WhRUGUk.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-2826604288969382257</id><published>2012-01-30T10:59:00.000-08:00</published><updated>2012-01-30T10:59:18.063-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T10:59:18.063-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><title>rsync - synchronizing two file trees strcuture</title><content type="html">&lt;b&gt;rsync - synchronizing two file trees strcuture&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
rsync is an amazing and powerful tool for moving files around. I know of people that use it for file transfers, keeping dns server records up-to-date, and along with sshd to remote restart the services when rsync reports a file change (how they do that, I don't know, I'm just told they do it).&lt;br /&gt;
&lt;br /&gt;
This article describes how you can use rsync to synchronize file trees. In this case, I'm using two websites to make sure one is a backup of the other. As an example, I'll be making sure that one box contains the same files as the other box in case I need to put the backup box into production, should a failure occur.&lt;br /&gt;
Overview&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;rsync can be used in six different ways, as documented in man rsync:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
1. for copying local files. This is invoked when neither source nor destination path contains a : separator&lt;br /&gt;
2. for copying from the local machine to a remote machine using a remote shell program as the transport (such as rsh or ssh). This is invoked when the destination path contains a single : separator.&lt;br /&gt;
3. for copying from a remote machine to the local machine using a remote shell program. This is invoked when the source contains a : separator.&lt;br /&gt;
4. for copying from a remote rsync server to the local machine. This is invoked when the source path contains a :: separator or a rsync:// URL.&lt;br /&gt;
5. for copying from the local machine to a remote rsync server. This is invoked when the destination path contains a :: separator.&lt;br /&gt;
6. for listing files on a remote machine. This is done the same way as rsync transfers except that you leave off the local destination.&lt;br /&gt;
&lt;br /&gt;
I'll only be looking at copying from a remote rsync server (4) to a local machine and when using a remote shell program (2).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Installing&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This was an easy port to install (aren't they all, for the most part?). Remember, I have the entire ports tree, so I did this:&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/net/rsync&lt;br /&gt;
# make config-recursive&lt;br /&gt;
# make install clean distclean&lt;br /&gt;
&lt;pre&gt;===&amp;gt; The following configuration options are available for rsync-3.0.9:
     POPT_PORT=off "Use popt from devel/popt instead of bundled one"
     SSH=on "Use SSH instead of RSH"
     FLAGS=off "File system flags support patch, adds --fileflags"
     ATIMES=off "Preserve access times, adds --atimes"
     ACL=off "Add backward-compatibility for the --acls option"
     ICONV=on "Add iconv support"
     TIMELIMIT=on "Time limit patch"
===&amp;gt; Use 'make config' to modify these settings
&lt;/pre&gt;If you don't have the ports tree installed, you have a bit more work to do.... As far as I know, you need rsync installed on both client and server, although you do not need to be running rsyncd unless you are connecting via method 4.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Setting up the server&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit /etc/rc.conf&lt;/b&gt;&lt;br /&gt;
# vi /etc/rc.conf&lt;br /&gt;
### enable rsyncd, using IPv4 instead of the default IPv6.&lt;br /&gt;
rsyncd_enable="YES"&lt;br /&gt;
rsyncd_flags="-4"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;You might run rsyncd manually. If your server only uses IPv4, then, make sure you add the "-4" argument to the command&lt;/b&gt;&lt;br /&gt;
# vi /usr/local/etc/rc.d/rsyncd&lt;br /&gt;
&lt;br /&gt;
Change:&lt;br /&gt;
command_args="--daemon"&lt;br /&gt;
&lt;br /&gt;
To:&lt;br /&gt;
command_args="-4 --daemon"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit /usr/local/etc/rsyncd.conf&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In this example, we're going to be using a remote rsync server (4). On the production web server, I created the /usr/local/etc/rsyncd.conf file. The contents is based on man rsyncd.conf. &lt;br /&gt;
&lt;br /&gt;
# vi /usr/local/etc/rsyncd.conf&lt;br /&gt;
address = 192.168.100.78&lt;br /&gt;
&lt;br /&gt;
charset=utf-8&lt;br /&gt;
&lt;br /&gt;
uid = www&lt;br /&gt;
gid = www&lt;br /&gt;
&lt;br /&gt;
use chroot = no&lt;br /&gt;
&lt;br /&gt;
max connections = 20&lt;br /&gt;
&lt;br /&gt;
syslog facility = local5&lt;br /&gt;
&lt;br /&gt;
log file = /var/log/rsyncd.log&lt;br /&gt;
&lt;br /&gt;
#pid file=/var/run/rsyncd.pid&lt;br /&gt;
#lock file=/var/run/rsyncd.lock&lt;br /&gt;
&lt;br /&gt;
max verbosity = 2&lt;br /&gt;
&lt;br /&gt;
transfer logging = yes&lt;br /&gt;
&lt;br /&gt;
[web]&lt;br /&gt;
hosts deny = 0.0.0.0/0.0.0.0&lt;br /&gt;
hosts allow = 192.168.1.2, 192.168.1.3&lt;br /&gt;
&lt;br /&gt;
auth users = rsync_bot1, rsync_bot2&lt;br /&gt;
secrets file = /usr/local/etc/rsyncd.secrets&lt;br /&gt;
&lt;br /&gt;
path = /www/rsync_tmp&lt;br /&gt;
comment = whoe www (approx 10gb)&lt;br /&gt;
&lt;br /&gt;
read only = no&lt;br /&gt;
&lt;br /&gt;
[home_ftp]&lt;br /&gt;
       uid = root&lt;br /&gt;
       gid = ftp&lt;br /&gt;
       hosts deny = 0.0.0.0/0.0.0.0&lt;br /&gt;
       hosts allow = 192.168.1.2&lt;br /&gt;
&lt;br /&gt;
       path = /home/ftp&lt;br /&gt;
       comment = ftp files&lt;br /&gt;
&lt;br /&gt;
       auth users = home_ftp_user0&lt;br /&gt;
       secrets file = /usr/local/etc/rsyncd.secrets&lt;br /&gt;
&lt;br /&gt;
       read only = no&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note&lt;/b&gt;: you can choose to put setting on global level or module (section) level.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Adding any local-net entries to your /etc/hosts file so that rsync's name lookup uses that information.&lt;/b&gt;&lt;br /&gt;
# vi /etc/hosts&lt;br /&gt;
192.168.1.2 test2&lt;br /&gt;
192.168.1.3 test3&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating Log file&lt;/b&gt;&lt;br /&gt;
# touch /var/log/rsyncd.log&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;automatically rotate logs&lt;/b&gt;&lt;br /&gt;
# vi /etc/newsyslog.conf&lt;br /&gt;
### rsync&lt;br /&gt;
/var/log/rsyncd.log 600 9 100000 * Z&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create the Secret File&lt;/b&gt;&lt;br /&gt;
# touch /usr/local/etc/rsyncd.secrets&lt;br /&gt;
&lt;br /&gt;
# vi /usr/local/etc/rsyncd.secrets&lt;br /&gt;
rsync_bot1:mypass&lt;br /&gt;
rsync_bot2:mypass&lt;br /&gt;
home_ftp_user0:mypass&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make /usr/local/etc/rsyncd.conf non-world readable:&lt;/b&gt;&lt;br /&gt;
# chmod 440 /usr/local/etc/rsyncd.secrets&lt;br /&gt;
# chown root:wheel /usr/local/etc/rsyncd.secrets&lt;br /&gt;
&lt;br /&gt;
You'll note that I'm running rsync as www:www (or rsync:rsync depends on your situation).&lt;br /&gt;
&lt;br /&gt;
# cat /etc/master.passwd | grep www &lt;br /&gt;
www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin&lt;br /&gt;
&lt;br /&gt;
# cat /etc/group | grep www&lt;br /&gt;
www:*:80:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Then I started the rsync daemon and verified it was running by doing this:&lt;/b&gt;&lt;br /&gt;
# /usr/local/etc/rc.d/rsyncd start&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Monitor rsync log file&lt;/b&gt;&lt;br /&gt;
# tail -F /var/log/rsyncd.log&lt;br /&gt;
rsyncd version 3.0.6 starting, listening on port 873&lt;br /&gt;
&lt;br /&gt;
# ps auxww | grep rsync&lt;br /&gt;
root 737 0.0 0.1 3128 1348 ?? Is 10:50AM 0:00.00 /usr/local/bin/rsync -4 --daemon&lt;br /&gt;
&lt;br /&gt;
# sockstat | grep rsync&lt;br /&gt;
root rsync 1763 4 tcp4 *:873 *:*&lt;br /&gt;
&lt;br /&gt;
Then I verified that I could connect to the daemon by doing this:&lt;br /&gt;
&lt;br /&gt;
# telnet localhost 873&lt;br /&gt;
Trying 127.0.0.1...&lt;br /&gt;
Connected to localhost.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
@RSYNCD: 21&lt;br /&gt;
&lt;br /&gt;
I determined the port 873 by looking at man rsyncd.conf.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Open rsync port in firewall.&lt;/b&gt;&lt;br /&gt;
# vi /usr/local/etc/ipfw.rules&lt;br /&gt;
### rsync&lt;br /&gt;
$IPF 260 allow tcp from 192.168.1.2 to any 873 in&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rotate rsync log file:&lt;/b&gt;&lt;br /&gt;
# vim /etc/newsyslog.conf&lt;br /&gt;
/var/log/rsyncd.log       600  7     100000 *     JC    /var/run/rsyncd.pid&lt;br /&gt;
&lt;br /&gt;
# /etc/rc.d/newsyslog restart&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Setting up the client&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You may have to install rsync on the client as well.. There wasn't much to set up on the client. I merely issued the following command. The rsync server in question is 192.168.1.1.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create the password file first&lt;/b&gt;&lt;br /&gt;
# echo "mypass" &amp;gt; /usr/local/etc/rsyncd.passwd_rsync_bot1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note&lt;/b&gt;: put &lt;b&gt;password ONLY&lt;/b&gt;. Do NOT put username!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Perform a dry run (pseudo):&lt;/b&gt;&lt;br /&gt;
# rsync -navu --stats --safe-links --password-file=/usr/local/etc/rsyncd.passwd_rsync_bot1 rsync_bot1@192.168.1.1::web /www/rsync_tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; -n parameter makes rsync perform a trial run preview that doesn't make any changes (and produces mostly the same output as a real run).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pulling remote files from the remote rsync daemon:&lt;/b&gt;&lt;br /&gt;
# rsync -avu --stats --safe-links --password-file=/usr/local/etc/rsyncd.passwd_rsync_bot1 rsync_bot1@192.168.1.1::web /www/rsync_tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note: -a&lt;/b&gt; parameter turns on archive mode. Bascially this causes rsync to recurse the directory copying all the files and directories and perserving things like case, permissions, and ownership on the target. (Note: Ownership may not be preserved if you are not logged in as the root user.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note: -v&lt;/b&gt; parameter turns on verbose mode.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;&lt;b&gt;Note&lt;/b&gt;: the reason why I added the &lt;b&gt;--safe-links&lt;/b&gt; parameter is because without it, the symbolic link files will be messed up.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pushing local files to the remote rsync daemon:&lt;/b&gt;&lt;br /&gt;
# rsync -avu --stats --safe-links --password-file=/usr/local/etc/rsyncd.passwd_rsync_bot1 /www/rsync_tmp/ rsync_bot1@192.168.1.1::web&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;&lt;b&gt;Note&lt;/b&gt;: do not forget the trailing slash of the directory path.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rsync between two local directories:&lt;/b&gt;&lt;br /&gt;
# rsync -avu --stats --safe-links --iconv=CP950,utf-8 --exclude='*.svn' --exclude='*.log' /source/path/ /destination/path/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; if the filenames on the source server contain traditional chinese characters, make sure you do include the --iconv option.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To mount a remote Microsoft shared samba SMB / CIFS directories folders:&lt;/b&gt;&lt;br /&gt;
# mkdir /path/to/local/mnt&lt;br /&gt;
# mount_smbfs -f 400 -d 500 -I 1.2.3.4 //Username@NetBIOS-Server-Name/SharedFolder /path/to/local/mnt&lt;br /&gt;
&lt;br /&gt;
-I 1.2.3.4 // Do not use NetBIOS name resolver and connect directly to host, which can be either a valid DNS name or an IP address.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Avoid password prompt:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Use smbutil to generate encrypted password:&lt;/b&gt;&lt;br /&gt;
# smbutil crypt MyPassword&lt;br /&gt;
$$14144762c293a0314e6e1&lt;br /&gt;
&lt;br /&gt;
You need to create a ~/.nsmbrc file as follows:&lt;br /&gt;
# vim ~/.nsmbrc&lt;br /&gt;
&lt;br /&gt;
Set username and password as follows:&lt;br /&gt;
&lt;br /&gt;
[NetBIOS-Server-Name:Username]&lt;br /&gt;
password=$$14144762c293a0314e6e1&lt;br /&gt;
&lt;br /&gt;
Now mount the directory as follows:&lt;br /&gt;
# mount_smbfs -f 400 -d 500 -N -I 10.1.2.3 //Username@NetBIOS-Server-Name/SharedFolder /path/to/local/mnt&lt;br /&gt;
&lt;br /&gt;
The -N option forces to read a password from ~/.nsmbrc file. At run time, mount_smbfs reads the ~/.nsmbrc file for additional configuration parameters and a password. If no password is found, mount_smbfs prompts for it. You need to use the -N option while writing a shell script.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; ~/.nsmbrc Keeps static parameters for connections and other information. See /usr/share/examples/smbfs/dot.nsmbrc for details.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; man mount_smbfs&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Mount the shared folder on system startup&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;mount_smbfs&lt;/b&gt; does not make the mount permanent. If the FreeBSD system is rebooted, you will have to mount the share again. To make the mount occur each time you start the FreeBSD system, you can put an entry in your /etc/fstab file. An example file would look like this:&lt;br /&gt;
&lt;br /&gt;
//myUser@serverName/mySharedFolder /mnt/mySharedFolder smbfs rw,-N,-I192.168.1.1 0 0&lt;br /&gt;
&lt;br /&gt;
If the share is password protected, don't forget to create ~/.nsmbrc with your usename and password.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Example:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
From:&lt;br /&gt;
/some_path/test_link/&lt;br /&gt;
&lt;br /&gt;
To:&lt;br /&gt;
/rsyncd-munged//some_path/test_link/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Other resource&lt;/b&gt;&lt;br /&gt;
# man rsync&lt;br /&gt;
&lt;br /&gt;
# man rsyncd.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Connecting to remote rsync server via SSH&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;ServerA&lt;/b&gt; 192.168.1.1 // the server that is running rsync server.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;ServerB&lt;/b&gt; 192.168.1.2 // the rsync client that is used for pulling and pushing files from the rsync server.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pulling remote files from the remote rsync server:&lt;/b&gt;&lt;br /&gt;
ServerB # rsync -e ssh -avu --stats my_account@192.168.1.1:/www/rsync_tmp/ /www/rsync_tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pushing local files to the remote rsync server:&lt;/b&gt;&lt;br /&gt;
ServerB # rsync -e ssh -avu --stats /www/rsync_tmp/ my_account@192.168.1.1:/www/rsync_tmp/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note&lt;/b&gt;: do not forget the trailing slash.&lt;br /&gt;
&lt;br /&gt;
ServerB # ssh-keygen -t dsa&lt;br /&gt;
&lt;br /&gt;
ServerB # scp ~/.ssh/id_dsa.pub my_account@192.168.1.1:/home/some_account&lt;br /&gt;
&lt;br /&gt;
ServerA # cat id_dsa.pub &amp;gt;&amp;gt; ~/some_account/.ssh/authorized_keys2&lt;br /&gt;
&lt;br /&gt;
ServerB # ssh my_account@192.168.1.1&lt;br /&gt;
&lt;br /&gt;
=====================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;FAQ&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Problem: name lookup failed for 192.168.100.157: hostname nor servname provided, or not known&lt;br /&gt;
&lt;br /&gt;
Solution: &lt;br /&gt;
&amp;gt; Is there a way to prevent rsyncd from doing reverse IP lookups on &lt;br /&gt;
&amp;gt; connecting clients? I didn't find any config option for this.&lt;br /&gt;
&lt;br /&gt;
There is no such option in the rsync code. I'd suggest adding any&lt;br /&gt;
local-net entries to your /etc/hosts file so that rsync's name lookup&lt;br /&gt;
uses that information.&lt;br /&gt;
&lt;br /&gt;
Problem: secrets file must be owned by root when running as root (see strict modes)&lt;br /&gt;
&lt;br /&gt;
Solution: Set both server side and client's secret file owned by root XD&lt;br /&gt;
&lt;br /&gt;
Problem: ERROR: module is read only&lt;br /&gt;
&lt;br /&gt;
Solution: add following line to the /usr/local/etc/rsyncd.conf file.&lt;br /&gt;
read only = no&lt;br /&gt;
=====================================================================&lt;br /&gt;
&lt;br /&gt;
&amp;gt; &amp;gt; @ERROR: access denied to home from localhost (127.0.0.1)&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; This is the important bit. This means that you got through &lt;br /&gt;
&amp;gt; to the rsync daemon and it rejected your access. The log &lt;br /&gt;
&amp;gt; file for the daemon will have more explicit information &lt;br /&gt;
&amp;gt; (which is hidden from the client on purpose), but I'd imagine &lt;br /&gt;
&amp;gt; that you need to add localhost to the list of acceptable IPs &lt;br /&gt;
&amp;gt; that are authorized to connect.&lt;br /&gt;
&lt;br /&gt;
Rsync.conf&lt;br /&gt;
-------------------------------------------------&lt;br /&gt;
use chroot = no&lt;br /&gt;
strict modes = yes&lt;br /&gt;
auth users = backup&lt;br /&gt;
secrets file = /etc/rsyncd.secrets&lt;br /&gt;
hosts allow = *, localhost, 127.0.0.1, 192.168.180.53&lt;br /&gt;
log file = /var/log/rsyncd.log&lt;br /&gt;
max verbosity = 2&lt;br /&gt;
transfer logging = yes&lt;br /&gt;
&lt;br /&gt;
[home]&lt;br /&gt;
path = /cygdrive/d/home/&lt;br /&gt;
exclude = .ssh/ .ssh/** TEST/ TEST/**&lt;br /&gt;
read only = no&lt;br /&gt;
timeout = 600&lt;br /&gt;
--------cut-other-modul-configuration---&lt;br /&gt;
========================================================================&lt;br /&gt;
- &amp;gt; I notice that the performance is pretty slow ranges between 2 and 6&lt;br /&gt;
&amp;gt; MB/s.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; The command that I use from a remote machine to this, the archiving&lt;br /&gt;
&amp;gt; host, is:&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; rsync -avuz -e ssh ./dir archsrv:/archive/DATA&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; An investigation with top shows that the system is cpu bound rather than&lt;br /&gt;
&amp;gt; IO bound and that the sshd process is consuming 75% of the CPU compared&lt;br /&gt;
&amp;gt; to the rsync process which uses about 25%.&lt;br /&gt;
&amp;gt; &lt;br /&gt;
&amp;gt; Why is ssh using so much CPU? It seems wrong to me. I would expect rsync&lt;br /&gt;
&amp;gt; to be using most as it has to do compression.&lt;br /&gt;
&lt;br /&gt;
ssh has to do encryption, which is pretty CPU-intensive stuff.&lt;br /&gt;
You can tell ssh to use an encryption method that is less CPU-intensive,&lt;br /&gt;
such as arcfour; your command would look like this:&lt;br /&gt;
&lt;br /&gt;
rsync -avuz -e 'ssh -c arcfour' ./dir archsrv:/archive/DATA&lt;br /&gt;
&lt;br /&gt;
Alternatively, if security permits, use an rsync daemon.&lt;br /&gt;
======================================&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/02/rsync-synchronizing-two-file-trees_19.html"&gt;http://gala4th.blogspot.com/2010/02/rsync-synchronizing-two-file-trees_19.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/02/ssh-ssh-keygen.html"&gt;不使用密碼的SSH連線 - ssh-keygen&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.cyberciti.biz/faq/mounting-a-nas-with-freebsd-mount_smbfs/"&gt;http://www.cyberciti.biz/faq/mounting-a-nas-with-freebsd-mount_smbfs/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blog.up-link.ro/freebsd-how-to-mount-smb-cifs-shares-under-freebsd/"&gt;http://blog.up-link.ro/freebsd-how-to-mount-smb-cifs-shares-under-freebsd/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.freebsddiary.org/rsync.php"&gt;http://www.freebsddiary.org/rsync.php&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.freebsddiary.org/secure-file-copy.php"&gt;http://www.freebsddiary.org/secure-file-copy.php&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.freebsddiary.org/ssh-authorized-keys.php"&gt;http://www.freebsddiary.org/ssh-authorized-keys.php&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blog.weithenn.org/2009/05/freebsdrsync.html"&gt;http://blog.weithenn.org/2009/05/freebsdrsync.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.sanitarium.net/golug/rsync_backups_2010.html"&gt;http://www.sanitarium.net/golug/rsync_backups_2010.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://slv922.pixnet.net/blog/post/26419814"&gt;http://slv922.pixnet.net/blog/post/26419814&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://lists.samba.org/archive/rsync/2005-October/013649.html"&gt;http://lists.samba.org/archive/rsync/2005-October/013649.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-2826604288969382257?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/jNvZC6aCPM0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/2826604288969382257/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=2826604288969382257" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/2826604288969382257?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/2826604288969382257?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/jNvZC6aCPM0/rsync-synchronizing-two-file-trees_19.html" title="rsync - synchronizing two file trees strcuture" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2010/02/rsync-synchronizing-two-file-trees_19.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04HRXY_cSp7ImA9WhRUGUk.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-8589057805663883854</id><published>2012-01-30T10:58:00.001-08:00</published><updated>2012-01-30T10:58:54.849-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T10:58:54.849-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><title>Setup a Pure-FTPd FTP server with virtual users</title><content type="html">Setup a Pure-FTPd FTP server with virtual users&lt;br /&gt;
&lt;br /&gt;
Pure-FTPd is a free (BSD), secure, production-quality and standard-conformant FTP server.&lt;br /&gt;
&lt;br /&gt;
This guide provides instructions for using the virtual user system to manage and control users. By using virtual users, FTP accounts can be administrated without affecting system accounts.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Let's initiate Pure-FTPd's installation by entering the following commands:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
% su&lt;br /&gt;
# portsnap update&lt;br /&gt;
# cd /usr/ports/ftp/pure-ftpd&lt;br /&gt;
# make config-recursive&lt;br /&gt;
&lt;br /&gt;
A menu containing Pure-FTPd options will pop-up. In my case, I've opted to leave these options at their defaults.&lt;br /&gt;
&lt;br /&gt;
# cat /var/db/ports/pure-ftpd/options&lt;br /&gt;
WITH_UTF8=true&lt;br /&gt;
WITH_LARGEFILE=true&lt;br /&gt;
&lt;br /&gt;
# make install clean distclean&lt;br /&gt;
# rehash&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Having finished the installation process we now move into the configuration stage. We'll start by copying the sample configuration file and set the configuration options:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /usr/local/etc&lt;br /&gt;
# cp pure-ftpd.conf.sample pure-ftpd.conf&lt;br /&gt;
# chmod 444 pure-ftpd.conf&lt;br /&gt;
&lt;br /&gt;
The chmod command was run to be able to edit the file (default permissions are set to -r--r--r--).&lt;br /&gt;
&lt;br /&gt;
# vim pure-ftpd.conf&lt;br /&gt;
# Port range for passive connections replies. - for firewalling.&lt;br /&gt;
PassivePortRange          30000 30900&lt;br /&gt;
&lt;br /&gt;
# IP address/port to listen to (default=all IP and port 21).&lt;br /&gt;
Bind 192.168.100.1,21&lt;br /&gt;
&lt;br /&gt;
# If you want to log all client commands, set this to "yes".&lt;br /&gt;
# This directive can be duplicated to also log server responses.&lt;br /&gt;
VerboseLog yes&lt;br /&gt;
&lt;br /&gt;
# PureDB user database (see README.Virtual-Users)&lt;br /&gt;
PureDB /usr/local/etc/pureftpd.pdb&lt;br /&gt;
&lt;br /&gt;
# Create an additional log file with transfers logged in the standard W3C&lt;br /&gt;
# format (compatible with most commercial log analyzers)&lt;br /&gt;
AltLog                     w3c:/var/log/pureftpd.log&lt;br /&gt;
&lt;br /&gt;
# Automatically create home directories if they are missing&lt;br /&gt;
CreateHomeDir yes&lt;br /&gt;
&lt;br /&gt;
# Disallow anonymous connections. Only allow authenticated users.&lt;br /&gt;
NoAnonymous                 yes&lt;br /&gt;
&lt;br /&gt;
# Disallow anonymous users to upload new files (no = upload is allowed)&lt;br /&gt;
AnonymousCantUpload         yes&lt;br /&gt;
&lt;br /&gt;
The CreateHomeDir option makes adding virtual users more easy by creating a user's home directory upon login (if it doesn't already exist).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;We can either import users with system-level accounts (defined in /etc/master.passwd) at once or create new users manually. To import users that already exist on your system into the virtual user database, enter these commands:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# pure-pwconvert &amp;gt;&amp;gt; /usr/local/etc/pureftpd.passwd&lt;br /&gt;
# chmod 600 /usr/local/etc/pureftpd.passwd&lt;br /&gt;
# pure-pw mkdb&lt;br /&gt;
&lt;br /&gt;
It should be noted that pure-pwconvert only imports accounts that have shell access. Accounts with the shell set to nologin have to be added manually.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To add users to the Pure-FTPd virtual user database manually, we need to create a system-level account that will be associated with virtual users. Create a new user named ftp like this:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# pw useradd -n ftp -s /sbin/nologin -w no -d /home/ftp -c "FTP user" -m&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; When you install pureftp, an ftp group is created, but no ftp user; this results in the error "mail pure-ftpd:(?:?) [ERROR] Unable to find the 'ftp' account". So we need to manually create the ftp user.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Having done this we can now add users to the virtual users database using the commands below:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# pure-pw useradd ftp_test -u ftp -g ftp -d /home/ftp/ftp_test&lt;br /&gt;
# pure-pw mkdb&lt;br /&gt;
&lt;br /&gt;
Replace user with the desired username. With -d flag, the user will be chrooted. If you want to give user access to the whole filesystem, use -D instead of -d.&lt;br /&gt;
&lt;br /&gt;
If you want to add additional users, just repeat the commands above with a different user.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Allow clients' IP addresse:&lt;/b&gt;&lt;br /&gt;
# pure-pw usermod user_name -r 209.17.11.12&lt;br /&gt;
# pure-pw mkdb&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To reset a user's password:&lt;/b&gt;&lt;br /&gt;
# pure-pw passwd user_name&lt;br /&gt;
# pure-pw mkdb&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To view info about one user:&lt;/b&gt;&lt;br /&gt;
# pure-pw show user_name&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To view a list of users:&lt;/b&gt;&lt;br /&gt;
# pure-pw list&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To remove a user:&lt;/b&gt;&lt;br /&gt;
# pure-pw userdel user_name&lt;br /&gt;
# pure-pw mkdb&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Now to start Pure-FTPd:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# /usr/local/etc/rc.d/pure-ftpd onestart&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Initiate a FTP connection to test the server:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
% ftp localhost&lt;br /&gt;
&lt;pre&gt;    Trying 127.0.0.1...
    Connected to localhost.
    220---------- Welcome to Pure-FTPd [TLS] ----------
    220-You are user number 2 of 50 allowed.
    220-Local time is now 13:39. Server port: 21.
    220-IPv6 connections are also welcome on this server.
    220 You will be disconnected after 15 minutes of inactivity.
    Name (localhost:username):
&lt;/pre&gt;Now log in with a user account created as explained above. Commands such as ls, cp, pwd and less work just like in tcsh and bash shells. To quit the FTP session type exit.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To configure Pure-FTPd to start at boot time:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# echo 'pureftpd_enable="YES"' &amp;gt;&amp;gt; /etc/rc.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To restart Pure-FTPd and determine if it is running:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# /usr/local/etc/rc.d/pure-ftpd restart&lt;br /&gt;
# /usr/local/etc/rc.d/pure-ftpd status&lt;br /&gt;
&lt;br /&gt;
# sockstat | grep :21&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rotate pure-ftpd log file:&lt;/b&gt;&lt;br /&gt;
# vim /etc/newsyslog.conf&lt;br /&gt;
/var/log/pureftpd.log       600  7     100000 *     JC    /var/run/pure-ftpd.pid&lt;br /&gt;
&lt;br /&gt;
# /etc/rc.d/newsyslog restart&lt;br /&gt;
&lt;br /&gt;
Pure-FTPd provides useful features for personal users as well as hosting providers. I've only touched the tip of the iceberg so do take a look at the project's website for the excellent documentation that is available. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;PF supports FTP servers and FTP clients behind NAT&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
WAN0 IP: 11.11.11.11&lt;br /&gt;
WAN1 IP: 22.22.22.22&lt;br /&gt;
&lt;br /&gt;
FTP0 server (behind NAT) IP: 192.168.100.1&lt;br /&gt;
FTP1 server (behind NAT) IP: 192.168.100.2&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.local&lt;br /&gt;
### ftp-proxy for outside world FTP clients accessing internal FTP server behand NAT.&lt;br /&gt;
/usr/sbin/setfib 0 /usr/sbin/ftp-proxy -R 192.168.100.1 -p 21 -b 11.11.11.11&lt;br /&gt;
/usr/sbin/setfib 1 /usr/sbin/ftp-proxy -R 192.168.100.2 -p 21 -b 22.22.22.22&lt;br /&gt;
&lt;br /&gt;
### Note: &lt;br /&gt;
### -b // bind to the external IP.&lt;br /&gt;
### -R // redirect to internal FTP server IP.&lt;br /&gt;
&lt;br /&gt;
### ftp-proxy for internal FTP clients behand NAT accessing outside world FTP servers.&lt;br /&gt;
/usr/sbin/ftp-proxy -p 8021 -b 127.0.0.1&lt;br /&gt;
&lt;br /&gt;
# vim /etc/pf.conf&lt;br /&gt;
### [FTP] RDR DMZ to Outside (through ftp-proxy)&lt;br /&gt;
### Note: make sure you have this line "ftpproxy_enable="YES"" in your /etc/rc.conf.&lt;br /&gt;
nat-anchor "ftp-proxy/*"&lt;br /&gt;
rdr-anchor "ftp-proxy/*"&lt;br /&gt;
rdr pass proto tcp from $dmz_if/24 to any port 21 -&amp;gt; 127.0.0.1 port 8021&lt;br /&gt;
&lt;br /&gt;
### enabloe log for debugging purpose.&lt;br /&gt;
block log all&lt;br /&gt;
&lt;br /&gt;
### [FTP] from ROUTER to ANY&lt;br /&gt;
pass out quick log on $wan_if0 proto tcp from $wan_if0 to any port 21 rtable 0&lt;br /&gt;
pass out quick log on $wan_if0 proto tcp from $wan_if0 to any port &amp;gt; 1023 rtable 0&lt;br /&gt;
&lt;br /&gt;
pass out quick log on $wan_if1 proto tcp from $wan_if1 to any port 21 rtable 1&lt;br /&gt;
pass out quick log on $wan_if1 proto tcp from $wan_if1 to any port &amp;gt; 1023 rtable 1&lt;br /&gt;
&lt;br /&gt;
### [FTP] from ANY to $dmz_ftp0_ip0 $dmz_ftp1_ip0&lt;br /&gt;
pass in quick log on $wan_if0 proto tcp from any to $wan_if0 port 21 rtable 0&lt;br /&gt;
pass in quick log on $wan_if0 proto tcp from any to $dmz_ftp0_ip0 port 30000:30900 rtable 0&lt;br /&gt;
pass in quick log on $wan_if1 proto tcp from any to $wan_if1 port 21 rtable 1&lt;br /&gt;
pass in quick log on $wan_if1 proto tcp from any to $dmz_ftp1_ip0 port 30000:30900 rtable 1&lt;br /&gt;
&lt;br /&gt;
pass out quick log on $dmz_if proto tcp from $dmz_if to $dmz_ftp0_ip0 port 21 rtable 0&lt;br /&gt;
pass out quick log on $dmz_if proto tcp from $dmz_if to $dmz_ftp0_ip0 port 30000:30900 rtable 0&lt;br /&gt;
pass out quick log on $dmz_if proto tcp from $dmz_if to $dmz_ftp1_ip0 port 21 rtable 1&lt;br /&gt;
pass out quick log on $dmz_if proto tcp from $dmz_if to $dmz_ftp1_ip0 port 30000:30900 rtable 1&lt;br /&gt;
&lt;br /&gt;
### [FTP] We need to have an anchor for ftp-proxy.&lt;br /&gt;
anchor "ftp-proxy/*"&lt;br /&gt;
&lt;br /&gt;
### [FTP] from DMZ to ANY&lt;br /&gt;
pass in quick log on $dmz_if proto tcp from $dmz_if/24 to any port 21 rtable 0&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Flush the pf.conf setting:&lt;/b&gt;&lt;br /&gt;
# pfctl -f /etc/pf.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Try to connect to ftp:&lt;/b&gt;&lt;br /&gt;
# ftp ftp.freebsd.org&lt;br /&gt;
Name: anonymous&lt;br /&gt;
Password: anonymous&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
Setup a Pure-FTPd FTP server with virtual users&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2012/01/setup-pure-ftpd-ftp-server-with-virtual.html"&gt;http://gala4th.blogspot.com/2012/01/setup-pure-ftpd-ftp-server-with-virtual.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2012/01/pf-supports-ftp-servers-and-ftp-clients.html"&gt;http://gala4th.blogspot.com/2012/01/pf-supports-ftp-servers-and-ftp-clients.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://forums.freebsd.org/showthread.php?t=591"&gt;http://forums.freebsd.org/showthread.php?t=591&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-8589057805663883854?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/yFOAy3PIojE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/8589057805663883854/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=8589057805663883854" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/8589057805663883854?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/8589057805663883854?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/yFOAy3PIojE/setup-pure-ftpd-ftp-server-with-virtual.html" title="Setup a Pure-FTPd FTP server with virtual users" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/setup-pure-ftpd-ftp-server-with-virtual.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04FR3g5eSp7ImA9WhRUGUk.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-6254591364048473596</id><published>2012-01-30T10:58:00.000-08:00</published><updated>2012-01-30T10:58:36.621-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T10:58:36.621-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="VPN" /><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><title>Set up OpenVPN server on FreeBSD running PF packet filter firewall and run VPN client on Windows 7 and FreeBSD 8.2</title><content type="html">&lt;b&gt;Set up OpenVPN server on FreeBSD running PF packet filter firewall and run VPN client on Windows 7 and FreeBSD 8.2&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
OpenVPN is a free and open source software application that implements virtual private network (VPN) techniques for creating secure point-to-point or site-to-site connections in routed or bridged configurations and remote access facilities. It uses a custom security protocol[2] that utilizes SSL/TLS for key exchange. It is capable of traversing network address translators (NATs) and firewalls. It was written by James Yonan and is published under the GNU General Public License (GPL)&lt;br /&gt;
&lt;br /&gt;
My server has two WAN connections from two different ISP, so the setting in this tutorial allows the VPN clients to connect to the VPN server with my two public IP addresses. However, you can still use this tutorial to set up the OpenVPN server with a single WAN interface.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;If you need help on how to set up multiple WAN interfaces with two different ISP:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/10/multiple-default-routes-gateways-with.html"&gt;http://gala4th.blogspot.com/2011/10/multiple-default-routes-gateways-with.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Running OpenVPN in different scenarios:&lt;/b&gt;&lt;br /&gt;
1. Single OpenVPN instance on single interface.&lt;br /&gt;
2. Multiple OpenVPN instances on single interface. Ex: you want different rules for each set of VPN clients.&lt;br /&gt;
3. Single OpenVPN instance on each of multiple interfaces.&lt;br /&gt;
4. Multiple OpenVPN instance on each of multiple interfaces.&lt;br /&gt;
&lt;br /&gt;
We will set up OpenVPN in &lt;b&gt;"Single OpenVPN instance on each of multiple interfaces"&lt;/b&gt; scenario.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install OpenVPN:&lt;/b&gt;&lt;br /&gt;
# cd /usr/ports/security/openvpn&lt;br /&gt;
# make config-recursive&lt;br /&gt;
# make config-recursive&lt;br /&gt;
# make config-recursive&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; run "make config-recursive" few times. You may enable a dependency the first time through that has its own configuration options.&lt;br /&gt;
&lt;br /&gt;
# make install&lt;br /&gt;
&lt;br /&gt;
# mkdir /usr/local/etc/openvpn&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;This /usr/local/etc/rc.d/openvpn script supports running multiple instances of openvpn. To run additional instances link this script to something like:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
# ln -s openvpn openvpn_foo&lt;br /&gt;
&lt;br /&gt;
and define additional openvpn_foo_* variables in one of:&lt;br /&gt;
/etc/rc.conf, /etc/rc.conf.local or /etc/rc.conf.d/openvpn_foo&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A list of avaiable interface on my server:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# ifconfig -l | tr ' ' '\n'&lt;br /&gt;
wan0 // IP 11.11.11.11. First WAN interface for my first ISP.&lt;br /&gt;
wan1 // IP 22.22.22.22. Second WAN interface for my second ISP.&lt;br /&gt;
dmz0 // IP 192.168.100.1 and 192.168.100.2. DMZ interface.&lt;br /&gt;
lan0 // IP 192.168.200.1 and 192.168.200.2. LAN interface.&lt;br /&gt;
tun0 // IP 10.8.0.1. First VPN interface for VPN clients connecting to first WAN interface.&lt;br /&gt;
tun1 // IP 10.9.0.1. Second VPN interface for VPN clients connecting to second WAN interface.&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.conf&lt;br /&gt;
ifconfig_wan0="inet 11.11.11.11 netmask 255.255.255.0"&lt;br /&gt;
ifconfig_wan1="inet 22.22.22.22 netmask 255.255.255.0"&lt;br /&gt;
&lt;br /&gt;
ifconfig_dmz0="inet 192.168.100.1 netmask 255.255.255.0"&lt;br /&gt;
ifconfig_dmz0_alias0="inet 192.168.100.2 netmask 255.255.255.255"&lt;br /&gt;
&lt;br /&gt;
ifconfig_lan0="inet 192.168.200.1 netmask 255.255.255.0"&lt;br /&gt;
ifconfig_lan0_alias0="inet 192.168.200.2 netmask 255.255.255.255"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;// Note: do this if you want to run one instance of OpenVPN on each of two interfaces.&lt;/b&gt;&lt;br /&gt;
# ln -s /usr/local/etc/rc.d/openvpn /usr/local/etc/rc.d/openvpn_wan0&lt;br /&gt;
# ln -s /usr/local/etc/rc.d/openvpn /usr/local/etc/rc.d/openvpn_wan1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sample configuration files can be found in:&lt;/b&gt;&lt;br /&gt;
# ls -l /usr/local/share/doc/openvpn/sample-config-files&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Copy the OpenVPN config file&lt;/b&gt;&lt;br /&gt;
# cp /usr/local/share/doc/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/openvpn_wan0.conf&lt;br /&gt;
&lt;br /&gt;
# cp /usr/local/share/doc/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/openvpn_wan1.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; The reason why we need to rename the config filename from server.conf to openvpn_foo.conf is because the /usr/local/etc/rc.d/openvpn script supports running multiple instances of openvpn. The openvpn script will try to read the config from the SCRIPT_NAME.conf. For example:&lt;br /&gt;
&lt;br /&gt;
If you are startup script is called /usr/local/etc/rc.d/openvpn_wan0, it will read config file from /usr/local/etc/openvpn/openvpn_wan0.conf.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit OpenVPN config file:&lt;/b&gt;&lt;br /&gt;
# vim /usr/local/etc/openvpn/openvpn_wan0.conf&lt;br /&gt;
### Specify device&lt;br /&gt;
dev tun&lt;br /&gt;
&lt;br /&gt;
### Which local IP address should OpenVPN&lt;br /&gt;
### listen on? (optional)&lt;br /&gt;
local 11.11.11.11&lt;br /&gt;
&lt;br /&gt;
### Certificates for VPN Authentication&lt;br /&gt;
ca /usr/local/etc/openvpn/keys/ca.crt&lt;br /&gt;
cert /usr/local/etc/openvpn/keys/server.crt&lt;br /&gt;
key /usr/local/etc/openvpn/keys/server.key # This file should be kept secret&lt;br /&gt;
&lt;br /&gt;
### Diffie hellman parameters&lt;br /&gt;
dh /usr/local/etc/openvpn/keys/dh1024.pem&lt;br /&gt;
&lt;br /&gt;
### Server and client IP and Pool&lt;br /&gt;
### The server will take 10.8.0.1 for itself,&lt;br /&gt;
### the rest will be made available to clients.&lt;br /&gt;
server 10.8.0.0 255.255.255.0&lt;br /&gt;
&lt;br /&gt;
# Maintain a record of client &amp;lt;-&amp;gt; virtual IP address&lt;br /&gt;
# associations in this file.  If OpenVPN goes down or&lt;br /&gt;
# is restarted, reconnecting clients can be assigned&lt;br /&gt;
# the same virtual IP address from the pool that was&lt;br /&gt;
# previously assigned.&lt;br /&gt;
ifconfig-pool-persist ipp.txt&lt;br /&gt;
&lt;br /&gt;
### Routes to push to the client.&lt;br /&gt;
### The specified network will be added automatically on the VPN client.&lt;br /&gt;
push "route 192.168.0.0 255.255.255.0"&lt;br /&gt;
&lt;br /&gt;
### Enable compression on the VPN link.&lt;br /&gt;
### If you enable it here, you must also&lt;br /&gt;
### enable it in the client config file.&lt;br /&gt;
comp-lzo&lt;br /&gt;
&lt;br /&gt;
### Make the link more resistant to connection failures&lt;br /&gt;
keepalive 10 120&lt;br /&gt;
persist-tun&lt;br /&gt;
persist-key&lt;br /&gt;
&lt;br /&gt;
### optional ?&lt;br /&gt;
#ping-timer-rem&lt;br /&gt;
&lt;br /&gt;
# It's a good idea to reduce the OpenVPN&lt;br /&gt;
# daemon's privileges after initialization.&lt;br /&gt;
#&lt;br /&gt;
# You can uncomment this out on non-Windows systems.&lt;br /&gt;
# By specifying 'nobody' OpenVPN service privileges are&lt;br /&gt;
# dropped to nobody. This increases system security.&lt;br /&gt;
user nobody&lt;br /&gt;
group nobody&lt;br /&gt;
&lt;br /&gt;
# By default, log messages will go to the syslog (or&lt;br /&gt;
# on Windows, if running as a service, they will go to&lt;br /&gt;
# the "\Program Files\OpenVPN\log" directory).&lt;br /&gt;
# Use log or log-append to override this default.&lt;br /&gt;
# "log" will truncate the log file on OpenVPN startup,&lt;br /&gt;
# while "log-append" will append to it.  Use one&lt;br /&gt;
# or the other (but not both).&lt;br /&gt;
;log         openvpn.log&lt;br /&gt;
log-append  /var/log/openvpn_wan0.log&lt;br /&gt;
&lt;br /&gt;
# Set the appropriate level of log&lt;br /&gt;
# file verbosity.&lt;br /&gt;
#&lt;br /&gt;
# 0 is silent, except for fatal errors&lt;br /&gt;
# 4 is reasonable for general usage&lt;br /&gt;
# 5 and 6 can help to debug connection problems&lt;br /&gt;
# 9 is extremely verbose&lt;br /&gt;
verb 3&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;For openvpn_wan1.conf, most settings are similar to the previous openvpn_wan0.conf file, except:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# vim /usr/local/etc/openvpn/openvpn_wan1.conf&lt;br /&gt;
### Which local IP address should OpenVPN&lt;br /&gt;
### listen on? (optional)&lt;br /&gt;
local 22.22.22.22&lt;br /&gt;
&lt;br /&gt;
### Server and client IP and Pool&lt;br /&gt;
### The server will take 10.9.0.1 for itself,&lt;br /&gt;
### the rest will be made available to clients.&lt;br /&gt;
server 10.9.0.0 255.255.255.0&lt;br /&gt;
&lt;br /&gt;
log-append  /var/log/openvpn_wan1.log&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Review the difference between openvpn_wan0.conf and openvpn_wan1.conf:&lt;/b&gt;&lt;br /&gt;
# diff /usr/local/etc/openvpn/openvpn_wan0.conf /usr/local/etc/openvpn/openvpn_wan1.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Logging&lt;/b&gt;&lt;br /&gt;
# touch /var/log/openvpn_wan0.log&lt;br /&gt;
# touch /var/log/openvpn_wan1.log&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rotate OpenVPN log files:&lt;/b&gt;&lt;br /&gt;
# vim /etc/newsyslog.conf&lt;br /&gt;
/var/log/openvpn_wan0.log 600 9 100000 * JC /var/run/openvpn_wan0.pid&lt;br /&gt;
/var/log/openvpn_wan1.log 600 9 100000 * JC /var/run/openvpn_wan1.pid&lt;br /&gt;
&lt;br /&gt;
# /etc/rc.d/newsyslog restart&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Copy easy-rsa script to the home directory&lt;/b&gt;&lt;br /&gt;
# cp -r /usr/local/share/doc/openvpn/easy-rsa ~&lt;br /&gt;
# find ~/easy-rsa/ -type d -print0 | xargs -0 -I @ chmod 700 @&lt;br /&gt;
# find ~/easy-rsa/ -type f -print0 | xargs -0 -I @ chmod 400 @&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make sure these scripts are executable:&lt;/b&gt;&lt;br /&gt;
# find ~/easy-rsa/2.0/ -type f -print0 | xargs -0 -I @ chmod u+x @&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Change follow lines in vars file to reflect your setting:&lt;/b&gt;&lt;br /&gt;
# cd ~/easy-rsa/2.0/&lt;br /&gt;
# vim ~/easy-rsa/2.0/vars&lt;br /&gt;
### These are the default values for fields&lt;br /&gt;
### which will be placed in the certificate.&lt;br /&gt;
### Don't leave any of these fields blank.&lt;br /&gt;
export KEY_COUNTRY="CA"&lt;br /&gt;
export KEY_PROVINCE="BC"&lt;br /&gt;
export KEY_CITY="Vancouver"&lt;br /&gt;
export KEY_ORG="Fort-Funston Ltd"&lt;br /&gt;
export KEY_EMAIL="me@myhost.mydomain"&lt;br /&gt;
export KEY_CN="CommonName_Can_Be_YourName_or_HostName"&lt;br /&gt;
export KEY_NAME="YourName"&lt;br /&gt;
export KEY_OU="UnitName_or_DepartmentName"&lt;br /&gt;
export PKCS11_MODULE_PATH="dummy"&lt;br /&gt;
export PKCS11_PIN="A_RANDOM_PASSWORD"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Very Important Step for FreeBSD/TCSH users. FreeBSD ships with tcsh as its native shell, at the time of writing the following scripts do not work. To get around this you must drop down to a bourne shell. To do this just type the following at a prompt:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# sh&lt;br /&gt;
# cd ~/easy-rsa/2.0/&lt;br /&gt;
&lt;br /&gt;
Now you can carry on with building the certificates, once you have built them you can exit back out to tcsh.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sourcing the vars file and other scripts:&lt;/b&gt;&lt;br /&gt;
# . vars&lt;br /&gt;
# ./clean-all&lt;br /&gt;
# ./build-ca&lt;br /&gt;
&lt;br /&gt;
You will have to answer a few questions on the last step, once this has been done your CA certs will be created in the keys subdirectory.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Generate certificate &amp;amp; key for server:&lt;/b&gt;&lt;br /&gt;
# ./build-key-server server&lt;br /&gt;
A challenge password []: LEAVE IT BLANK AND PRESS ENTER&lt;br /&gt;
An optional company name []: LEAVE IT BLANK AND PRESS ENTER&lt;br /&gt;
&lt;br /&gt;
Again answer the questions and the certs will be placed in the keys subdirectory.&lt;br /&gt;
&lt;br /&gt;
Generate certificates &amp;amp; keys for 3 clients (each client will require their own certificates, if multiple clients log in with the same certs then they will be assigned the same ips and will kick each other off the network):&lt;br /&gt;
&lt;br /&gt;
Generating client certificates is very similar to the previous step. You need to ensure that all your details are the same as for the CA, apart from the common name, which needs to be different for each client. For the sake of clarity this should relate to person who is assigned this vpn certificate. All of these details can be found in keys/server.crt for the server and keys/client*.crt for the client details.&lt;br /&gt;
&lt;br /&gt;
# ./build-key client1&lt;br /&gt;
# ./build-key client2&lt;br /&gt;
# ./build-key client3&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Generate Diffie Hellman parameters&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Diffie Hellman parameters must be generated for the OpenVPN server:&lt;br /&gt;
&lt;br /&gt;
# ./build-dh&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Exit the sh shell:&lt;/b&gt;&lt;br /&gt;
# exit&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Now move the whole keys directory to /usr/local/etc/openvpn:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# mv ~/easy-rsa/2.0/keys /usr/local/etc/openvpn/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Protect our certificate keys directory and config files for only root can see it.&lt;/b&gt;&lt;br /&gt;
# find /usr/local/etc/openvpn/keys/ -type d -print0 | xargs -0 -I @ sh -c 'chmod 700 @ ; chown root:wheel @'&lt;br /&gt;
# find /usr/local/etc/openvpn/keys/ -type f -print0 | xargs -0 -I @ sh -c 'chmod 400 @ ; chown root:wheel @'&lt;br /&gt;
# find /usr/local/etc/openvpn/ -type f -name '*.conf' -print0 | xargs -0 -I @ sh -c 'chmod 400 @ ; chown root:wheel @'&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;You need to edit /etc/rc.conf if you set up single instance of OpenVPN with single interface:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; I have commented out following lines because I set to start OpenVPN daemon in /etc/rc.local later.&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.conf&lt;br /&gt;
#openvpn_wan0_enable="YES"&lt;br /&gt;
#openvpn_wan0_configfile="/usr/local/etc/openvpn/openvpn_wan0.conf"&lt;br /&gt;
&lt;br /&gt;
#openvpn_wan1_enable="YES"&lt;br /&gt;
#openvpn_wan1_configfile="/usr/local/etc/openvpn/openvpn_wan1.conf"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;We will be using the setfib command to run our utilities with an different routing table:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; You do not need the setfib command if you are hosting your OpenVPN server with single WAN interface.&lt;br /&gt;
&lt;br /&gt;
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.rtable0&lt;br /&gt;
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.rtable1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit sshd_config.* config file:&lt;/b&gt;&lt;br /&gt;
# vim /etc/ssh/sshd_config.rtable0&lt;br /&gt;
### IP address of first WAN interface&lt;br /&gt;
ListenAddress 11.11.11.11&lt;br /&gt;
### IP address of DMZ interface&lt;br /&gt;
ListenAddress 192.168.100.1&lt;br /&gt;
### IP address of LAN interface&lt;br /&gt;
ListenAddress 192.168.200.1&lt;br /&gt;
&lt;br /&gt;
# vim /etc/ssh/sshd_config.rtable1&lt;br /&gt;
### IP address of second WAN interface&lt;br /&gt;
ListenAddress 22.22.22.22&lt;br /&gt;
### IP address of DMZ interface&lt;br /&gt;
ListenAddress 192.168.100.2&lt;br /&gt;
### IP address of LAN interface&lt;br /&gt;
ListenAddress 192.168.200.2&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; Multiple ListenAddress options are permitted.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; you can let sshd to listen to the IP address of the tunnel interface. However, I do not recommend you do so. Because if OpenVPN did not start properly, sshd will have problem to start as well (because it could not listen to the specified IP address).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit rc.local:&lt;/b&gt;&lt;br /&gt;
# vim /etc/rc.local&lt;br /&gt;
### add first routing table for first WAN interface for first ISP network.&lt;br /&gt;
/usr/sbin/setfib 0 /sbin/route delete default&lt;br /&gt;
/usr/sbin/setfib 0 /sbin/route add default 11.11.11.11&lt;br /&gt;
&lt;br /&gt;
### add second routing table for second WAN interface for second ISP network.&lt;br /&gt;
/usr/sbin/setfib 1 /sbin/route delete default&lt;br /&gt;
/usr/sbin/setfib 1 /sbin/route add default 22.22.22.22&lt;br /&gt;
&lt;br /&gt;
### start OpenVPN on the first WAN interface.&lt;br /&gt;
/usr/sbin/setfib 0 /usr/local/etc/rc.d/openvpn_wan0 onestart&lt;br /&gt;
&lt;br /&gt;
### start OpenVPN on the second WAN interface.&lt;br /&gt;
/usr/sbin/setfib 1 /usr/local/etc/rc.d/openvpn_wan1 onestart&lt;br /&gt;
&lt;br /&gt;
### Use different routing table for each sshd daemon.&lt;br /&gt;
### Note: we need to start SSH after OpenVPN started&lt;br /&gt;
### since the IP address of tunnel interface (for VPN) has been listened by sshd,&lt;br /&gt;
### which is defined in the sshd_config.rtable0 and sshd_config.rtable1 config file.&lt;br /&gt;
### Note: make sure the line 'sshd_enable="YES"' has bee commented out&lt;br /&gt;
### or removed from /etc/rc.conf file. We will start sshd in /etc/rc.local file.&lt;br /&gt;
/usr/sbin/setfib 0 /usr/sbin/sshd -f /etc/ssh/sshd_config.rtable0&lt;br /&gt;
/usr/sbin/setfib 1 /usr/sbin/sshd -f /etc/ssh/sshd_config.rtable1&lt;br /&gt;
&lt;br /&gt;
### Flush PF rules after OpenVPN and SSH daemons started&lt;br /&gt;
### Note: the reason is because there are some settings related to these VPN&lt;br /&gt;
### interface tun0 and tun1. So we need to flush the PF rules after OpenVPN loaded.&lt;br /&gt;
/sbin/pfctl -f /etc/pf.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Comment out or remove sshd_enable="YES" line in /etc/rc.conf:&lt;/b&gt;&lt;br /&gt;
# vim /etc/rc.conf&lt;br /&gt;
### Note: commented out for multiple WAN routes setup. SSH daemon will be started in /etc/rc.local file.&lt;br /&gt;
#sshd_enable="YES"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Let's start OpenVPN server manually now:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# setfib 0 /usr/local/etc/rc.d/openvpn_wan0 onestart&lt;br /&gt;
Starting openvpn_wan0.&lt;br /&gt;
add net 10.8.0.0: gateway 10.8.0.2&lt;br /&gt;
&lt;br /&gt;
# setfib 1 /usr/local/etc/rc.d/openvpn_wan1 onestart&lt;br /&gt;
Starting openvpn_wan1.&lt;br /&gt;
add net 10.9.0.0: gateway 10.9.0.2&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make sure the network and the gateway have been correctly added:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# setfib 0 netstat -rn | egrep '10.[8|9].0'&lt;br /&gt;
10.8.0.0/24        10.8.0.2           UGS         0        0   tun0&lt;br /&gt;
10.8.0.1           link#6             UHS         0        0    lo0&lt;br /&gt;
10.8.0.2           link#6             UH          0        0   tun0&lt;br /&gt;
10.9.0.1           link#7             UHS         0        0    lo0&lt;br /&gt;
10.9.0.2           link#7             UH          0        0   tun1&lt;br /&gt;
&lt;br /&gt;
# setfib 1 netstat -rn | egrep '10.[8|9].0'&lt;br /&gt;
10.8.0.2           link#6             UH          0        0   tun0&lt;br /&gt;
10.9.0.0/24        10.9.0.2           UGS         0        0   tun1&lt;br /&gt;
10.9.0.2           link#7             UH          0        0   tun1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;In some cases, the network did not be added successfully, you will need to add the network maually:&lt;/b&gt;&lt;br /&gt;
# setfib 0 route add 10.8.0.0/24 10.8.0.2&lt;br /&gt;
# setfib 1 route add 10.9.0.0/24 10.9.0.2&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;You should have seen two different IP addresses are listening port 1194:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# netstat -an | grep 1194&lt;br /&gt;
udp4       0      0 11.11.11.11.1194    *.*&lt;br /&gt;
udp4       0      0 22.22.22.22.1194    *.*&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;You should have seen two different process IDs are running:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# ls -l /var/run/openvpn*.pid&lt;br /&gt;
-rw-r--r--  1 root  wheel  6 Dec  5 15:49 /var/run/openvpn_wan1.pid&lt;br /&gt;
-rw-r--r--  1 root  wheel  6 Dec  5 15:44 /var/run/openvpn_wan0.pid&lt;br /&gt;
&lt;br /&gt;
# ifconfig | grep tun&lt;br /&gt;
tun0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; metric 0 mtu 1500&lt;br /&gt;
tun1: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; metric 0 mtu 1500&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Let's start ssh daemon now:&lt;/b&gt;&lt;br /&gt;
# /usr/sbin/setfib 0 /usr/sbin/sshd -f /etc/ssh/sshd_config.rtable0&lt;br /&gt;
# /usr/sbin/setfib 1 /usr/sbin/sshd -f /etc/ssh/sshd_config.rtable1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;See port 22 is binding to which IP addresses:&lt;/b&gt;&lt;br /&gt;
# netstat -an | grep 22&lt;br /&gt;
tcp4       0      0 11.11.11.11.22      *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 192.168.100.1.22            *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 192.168.200.1.22       *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 10.8.0.1.22       *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 22.22.22.22.22      *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 192.168.100.2.22            *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 192.168.200.2.22       *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 10.9.0.1.22       *.*                    LISTEN&lt;br /&gt;
tcp4       0      0 *.22                   *.*                    LISTEN&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To show listening/opening TCP port:&lt;/b&gt;&lt;br /&gt;
# sockstat -Ptcp&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To show listening/opening UDP port:&lt;/b&gt;&lt;br /&gt;
# sockstat -Pudp&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; man sockstat&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Restart the machine and re-check everything is fine after reboot:&lt;/b&gt;&lt;br /&gt;
# sync; sync; sync; reboot&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit pf.conf PF firewall setting:&lt;/b&gt;&lt;br /&gt;
# vim /etc/pf.conf&lt;br /&gt;
wan_if0 = "wan0"&lt;br /&gt;
wan_if1 = "wan1"&lt;br /&gt;
&lt;br /&gt;
dmz_if = "dmz0"&lt;br /&gt;
lan_if = "lan0"&lt;br /&gt;
&lt;br /&gt;
### Note: the reason why we specified VPN network below is because we want to avoid&lt;br /&gt;
### PF parse host specification error. Since PF runs before OpenVPN starts,&lt;br /&gt;
### PF could not figure it out the VPN network until OpenVPN started.&lt;br /&gt;
vpn_if0 = "tun0"&lt;br /&gt;
vpn_net0 = '"10.8.0.0/24"'&lt;br /&gt;
vpn_if1 = "tun1"&lt;br /&gt;
vpn_net1 = '"10.9.0.0/24"'&lt;br /&gt;
&lt;br /&gt;
icmp_types = "{echoreq echorep unreach}"&lt;br /&gt;
&lt;br /&gt;
### [NAT] the VPN connections (for access to the remote secure networks)&lt;br /&gt;
nat on $wan_if0 from $vpn_net0to any -&amp;gt; $wan_if0&lt;br /&gt;
nat on $wan_if1 from $vpn_net1 to any -&amp;gt; $wan_if1&lt;br /&gt;
&lt;br /&gt;
### [VPN] Inbound from Outside&lt;br /&gt;
### Establish VPN connections on each WAN interface.&lt;br /&gt;
pass in quick on $wan_if0 proto udp from any to $wan_if0 port 1194 keep state rtable 0&lt;br /&gt;
pass in quick on $wan_if1 proto udp from any to $wan_if1 port 1194 keep state rtable 1&lt;br /&gt;
&lt;br /&gt;
### [SSH] Inbound from VPN to ANY&lt;br /&gt;
pass in quick log on $vpn_if0 proto tcp from $vpn_net0to any port 22 flags S/SA keep state rtable 0&lt;br /&gt;
pass in quick log on $vpn_if1 proto tcp from $vpn_net1 to any port 22 flags S/SA keep state rtable 1&lt;br /&gt;
&lt;br /&gt;
### [SSH] Outbound to LAN&lt;br /&gt;
pass out quick log on $lan_if proto tcp from {$dmz_if/24 $lan_if/24 $vpn_if0/24} to $lan_if/24 port 22 flags S/SA keep state rtable 0&lt;br /&gt;
pass out quick log on $lan_if proto tcp from {$vpn_net1} to $lan_if/24 port 22 flags S/SA keep state rtable 1&lt;br /&gt;
&lt;br /&gt;
### [SSH] Outbound to DMZ&lt;br /&gt;
pass out quick log on $dmz_if proto tcp from {$dmz_if/24 $lan_if/24 $vpn_if0/24} to $dmz_if/24 port 22 flags S/SA keep state rtable 0&lt;br /&gt;
pass out quick log on $dmz_if proto tcp from {$vpn_net1} to $dmz_if/24 port 22 flags S/SA keep state rtable 1&lt;br /&gt;
&lt;br /&gt;
### [ICMP] Inbound from VPN&lt;br /&gt;
pass in quick on $vpn_if0 proto icmp from $vpn_net0to any icmp-type $icmp_types rtable 0&lt;br /&gt;
pass in quick on $vpn_if1 proto icmp from $vpn_net1 to any icmp-type $icmp_types rtable 1&lt;br /&gt;
&lt;br /&gt;
### [ICMP] Inbound from Outside&lt;br /&gt;
pass in quick log on $wan_if0 proto icmp from any to $wan_if0 icmp-type $icmp_types rtable 0&lt;br /&gt;
pass in quick log on $wan_if1 proto icmp from any to $wan_if1 icmp-type $icmp_types rtable 1&lt;br /&gt;
&lt;br /&gt;
### [ICMP] Outbound to Outside&lt;br /&gt;
pass out quick on $wan_if0 proto icmp from $wan_if0 to any icmp-type $icmp_types rtable 0&lt;br /&gt;
pass out quick on $wan_if1 proto icmp from $wan_if1 to any icmp-type $icmp_types rtable 1&lt;br /&gt;
&lt;br /&gt;
### [ICMP] Outbound to LAN&lt;br /&gt;
pass out quick log on $lan_if proto icmp from {$lan_if $dmz_if/24 $vpn_if0/24} to $lan_if/24 icmp-type $icmp_types rtable 0&lt;br /&gt;
pass out quick log on $lan_if proto icmp from {$vpn_net1} to $lan_if/24 icmp-type $icmp_types rtable 1&lt;br /&gt;
&lt;br /&gt;
### [ICMP] Outbound to DMZ&lt;br /&gt;
pass out quick log on $dmz_if proto icmp from {$dmz_if $lan_if/24 $vpn_if0/24} to $dmz_if/24 icmp-type $icmp_types rtable 0&lt;br /&gt;
pass out quick log on $dmz_if proto icmp from {$vpn_net1} to $dmz_if/24 icmp-type $icmp_types rtable 1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Watch the pflog logged packets in real time:&lt;/b&gt;&lt;br /&gt;
# tcpdump -n -e -ttt -i pflog0&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Watch the icmp packect of an interface:&lt;/b&gt;&lt;br /&gt;
# tcpdump -ni wan0 icmp&lt;br /&gt;
# tcpdump -ni wan1 icmp&lt;br /&gt;
# tcpdump -ni dmz0 icmp&lt;br /&gt;
# tcpdump -ni tun0 icmp&lt;br /&gt;
# tcpdump -ni tun1 icmp&lt;br /&gt;
&lt;br /&gt;
# tcpdump -tt -i tun0&lt;br /&gt;
&lt;br /&gt;
# tail /usr/local/etc/openvpn/openvpn-status.log&lt;br /&gt;
&lt;br /&gt;
# tail /var/log/openvpn_wan0.log&lt;br /&gt;
&lt;br /&gt;
# tail /var/log/openvpn_wan1.log&lt;br /&gt;
&lt;br /&gt;
# tail /var/log/messages&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Download OpenVPN 2.2.1 client for Windows:&lt;/b&gt;&lt;br /&gt;
http://openvpn.net/index.php/open-source/downloads.html&lt;br /&gt;
&lt;br /&gt;
Once this is installed you will need to copy the following files from your server /usr/local/etc/openvpn/keys directory to the Windows PC C:\Program Files\Openvpn\config directory (this should be done in as secure a manner as possible, i.e. USB Stick or floppy rather than email!!!):&lt;br /&gt;
&lt;br /&gt;
ca.crt&lt;br /&gt;
client1.crt&lt;br /&gt;
client1.key&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; For the next client you will need to copy the client2.crt and client2.key files to prevent issues later.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create VPN config file:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
create a myvpn.ovpn file in C:\Program Files\Openvpn\config and insert the following:&lt;br /&gt;
&lt;br /&gt;
client&lt;br /&gt;
remote nic1.myserver.com 1194&lt;br /&gt;
#remote nic2.myserver.com 1194&lt;br /&gt;
dev tun&lt;br /&gt;
comp-lzo&lt;br /&gt;
&lt;br /&gt;
ca ca.crt&lt;br /&gt;
cert client1.crt&lt;br /&gt;
key client1.key&lt;br /&gt;
&lt;br /&gt;
# Set log file verbosity.&lt;br /&gt;
verb 3&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Turn off the firewall for the new Interface:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On Windows XP, the firewall can be accessed by:&lt;/b&gt;&lt;br /&gt;
Control Panel -&amp;gt; Security Center -&amp;gt; Windows Firewall -&amp;gt; Advanced. In the Network Connection Settings control, uncheck the box corresponding to the TAP-Win32 adapter.&lt;br /&gt;
&lt;br /&gt;
Now right-click the OpenVPN Icon in your Taskbar and click "connect". Once connected try pinging the remote interface and check (using tracert) that the remote network is available. Use tcpdump on the server to check traffic too:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;On Windows 7, you must run OpenVPN as an administrator by:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
right click on openvpn-gui-1.0.3.exe &amp;gt; Property &amp;gt; Shortcut &amp;gt; &lt;b&gt;Run this program as an administrator&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
right click on openvpn-gui-1.0.3.exe &amp;gt; Property &amp;gt; Compatibility &amp;gt; &lt;b&gt;Run this program as an administrator&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
cmd&amp;gt; tracert&lt;br /&gt;
&lt;br /&gt;
cmd&amp;gt; ping 10.8.0.1&lt;br /&gt;
cmd&amp;gt; ping 10.9.0.1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Use Firewall's VPN IP address to connecto the firewall:&lt;/b&gt;&lt;br /&gt;
cmd&amp;gt; putty.exe username@10.8.0.1&lt;br /&gt;
cmd&amp;gt; putty.exe username@10.9.0.1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; If you want to ssh to the IP address of the firewall's LAN/DMZ interface, make sure you do set up your sshd to listen to these IP addresses with proper routing table.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Use FreeBSD as a VPN client:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/security/openvpn&lt;br /&gt;
# make config-recursive&lt;br /&gt;
# make config-recursive&lt;br /&gt;
# make config-recursive&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; run "make config-recursive" few times. You may enable a dependency the first time through that has its own configuration options.&lt;br /&gt;
&lt;br /&gt;
# make install&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Link the openvpn startup script:&lt;/b&gt;&lt;br /&gt;
# ln -s /usr/local/etc/rc.d/openvpn /usr/local/etc/rc.d/openvpn_client&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create OpenVPN directory:&lt;/b&gt;&lt;br /&gt;
# mkdir -p /usr/local/etc/openvpn/keys&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Put following three files to /usr/local/etc/openvpn/keys:&lt;/b&gt;&lt;br /&gt;
ca.crt&lt;br /&gt;
client1.crt&lt;br /&gt;
client1.key&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Protect our certificate keys directory and config files for only root can see it.&lt;/b&gt;&lt;br /&gt;
# find /usr/local/etc/openvpn/keys/ -type d -print0 | xargs -0 -I @ sh -c 'chmod 700 @ ; chown root:wheel @'&lt;br /&gt;
# find /usr/local/etc/openvpn/keys/ -type f -print0 | xargs -0 -I @ sh -c 'chmod 400 @ ; chown root:wheel @'&lt;br /&gt;
# find /usr/local/etc/openvpn/ -type f -name '*.conf' -print0 | xargs -0 -I @ sh -c 'chmod 400 @ ; chown root:wheel @'&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;You will need to copy the client.conf instead of server.conf from /usr/local/share/doc/openvpn/sample-config-files directory:&lt;/b&gt;&lt;br /&gt;
# cp /usr/local/share/doc/openvpn/sample-config-files/client.conf /usr/local/etc/openvpn/openvpn_client.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit openvpn_client.conf:&lt;/b&gt;&lt;br /&gt;
# vim /usr/local/etc/openvpn/openvpn_client.conf&lt;br /&gt;
client&lt;br /&gt;
dev tun&lt;br /&gt;
proto udp&lt;br /&gt;
&lt;br /&gt;
# The hostname/IP and port of the server.&lt;br /&gt;
# You can have multiple remote entries&lt;br /&gt;
# to load balance between the servers.&lt;br /&gt;
remote 11.11.11.11 1194&lt;br /&gt;
;remote my-server-2 1194&lt;br /&gt;
&lt;br /&gt;
# Downgrade privileges after initialization (non-Windows only)&lt;br /&gt;
user nobody&lt;br /&gt;
group nobody&lt;br /&gt;
&lt;br /&gt;
# Try to preserve some state across restarts.&lt;br /&gt;
persist-key&lt;br /&gt;
persist-tun&lt;br /&gt;
&lt;br /&gt;
# Certificates for VPN Authentication&lt;br /&gt;
ca /usr/local/etc/openvpn/keys/ca.crt&lt;br /&gt;
cert /usr/local/etc/openvpn/keys/client1.crt&lt;br /&gt;
key /usr/local/etc/openvpn/keys/client1.key&lt;br /&gt;
&lt;br /&gt;
# Verify server certificate by checking&lt;br /&gt;
# that the certicate has the nsCertType&lt;br /&gt;
# field set to "server".  This is an&lt;br /&gt;
# important precaution to protect against&lt;br /&gt;
# a potential attack discussed here:&lt;br /&gt;
#  http://openvpn.net/howto.html#mitm&lt;br /&gt;
ns-cert-type server&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.conf&lt;br /&gt;
openvpn_client_enable="YES"&lt;br /&gt;
openvpn_client_configfile="/usr/local/etc/openvpn/openvpn_client.conf"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Start OpenVPN client:&lt;/b&gt;&lt;br /&gt;
# /usr/local/etc/rc.d/openvpn_client start&lt;br /&gt;
&lt;br /&gt;
# tail -F /var/log/messages&lt;br /&gt;
&lt;br /&gt;
# ifconfig&lt;br /&gt;
tun0: flags=8051&amp;lt;UP,POINTOPOINT,RUNNING,MULTICAST&amp;gt; metric 0 mtu 1500&lt;br /&gt;
        options=80000&amp;lt;LINKSTATE&amp;gt;&lt;br /&gt;
        inet 10.8.0.6 --&amp;gt; 10.8.0.5 netmask 0xffffffff&lt;br /&gt;
        Opened by PID 98483&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Display the full output line of ps process status command:&lt;/b&gt;&lt;br /&gt;
# ps -auxww | grep openvpn&lt;br /&gt;
nobody   1015  /usr/local/sbin/openvpn --cd /usr/local/etc/openvpn --daemon openvpn_wan0 --config /usr/local/etc/openvpn/openvpn_wan0.conf --writepid /var/run/openvpn_wan0.pid&lt;br /&gt;
nobody   1035  /usr/local/sbin/openvpn --cd /usr/local/etc/openvpn --daemon openvpn_wan1 --config /usr/local/etc/openvpn/openvpn_wan1.conf --writepid /var/run/openvpn_wan1.pid&lt;br /&gt;
&lt;br /&gt;
# ls -l /var/run/openvpn*&lt;br /&gt;
-rw-r--r--  1 root  wheel  6 Dec 21 12:53 /var/run/openvpn_client.pid&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Difference Between TUN and TAP&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In computer networking, TUN and TAP are virtual network kernel devices. They are network devices that are supported entirely in software, which is different from ordinary network devices that are backed up by hardware network adapters.&lt;br /&gt;
&lt;br /&gt;
TAP (as in network tap) simulates an Ethernet device and it operates with layer 2 packets such as Ethernet frames. TUN (as in network TUNnel) simulates a network layer device and it operates with layer 3 packets such as IP packets. TAP is used to create a network bridge, while TUN is used with routing.&lt;br /&gt;
&lt;br /&gt;
Packets sent by an operating system via a TUN/TAP device are delivered to a user-space program that attaches itself to the device. A user-space program may also pass packets into a TUN/TAP device. In this case TUN/TAP device delivers (or "injects") these packets to the operating system network stack thus emulating their reception from an external source.&lt;br /&gt;
===&lt;br /&gt;
As far as I could see, tap allows netbios broadcast to propagate across the&lt;br /&gt;
VPN so Windows clients can find network shares by PC name  even if no WINS&lt;br /&gt;
server is being used; with tun, either you find network shares in some other&lt;br /&gt;
way (by IP or DNS, for example) or you need to have WINS running (which often&lt;br /&gt;
amounts to "wins proxy = yes" in smb.conf).&lt;br /&gt;
&lt;br /&gt;
On the other hand, I do not feel comfortable in having VPN clients appear as&lt;br /&gt;
if physically attached to the LAN (this is what bridging with TAP amounts to)&lt;br /&gt;
and prefer routing with tun as it makes easier to write appropriate firewall&lt;br /&gt;
rules for VPN clients.&lt;br /&gt;
===&lt;br /&gt;
if it's ok to create vpn on layer 3 [ one more hop between subnets ] - go for tun.&lt;br /&gt;
&lt;br /&gt;
if you need to bridge two ethernet segments in two different locations - then use tap. in such setup you can have computers in the same ip subnet [ eg 10.0.0.0/24 ] on both ends of vpn, and they'll be able to 'talk' to each other directly without any changes in their routing tables. vpn will act like ethernet switch. this might sound cool and is useful in some cases but i would advice not to go for it unless you really need it. if you choose such layer 2 bridging setup - there will be a bit of 'garbage' [ that is broadcast packets ] going across your vpn.&lt;br /&gt;
===&lt;br /&gt;
I always set up tun. Tap is used by ethernet bridging in OpenVPN and introduces an unprecendented level of complexity that is simply not worth bothering with. Usually when a VPN needs to be installed, its needed now, and complex deployments don't come fast.&lt;br /&gt;
===&lt;br /&gt;
I chose "tap" when setting up a VPN for a friend who owned a small business because his office uses a tangle of Windows machines, commercial printers, and a Samba file server. Some of them use pure TCP/IP, some seem to only use NetBIOS (and thus need Ethernet broadcast packets) to communicate, and some I'm not even sure of.&lt;br /&gt;
&lt;br /&gt;
If I had chosen "tun", I would probably have faced lots of broken services — lots of things that worked while you are in the office physically, but then would break when you went off-site and your laptop couldn't "see" the devices on the Ethernet subnet anymore.&lt;br /&gt;
&lt;br /&gt;
But by choosing "tap", I tell the VPN to make remote machines feel exactly like they're on the LAN, with broadcast Ethernet packets and raw Ethernet protocols available for communicating with printers and file servers and for powering their Network Neighborhood display. It works great, and I never get reports of things that don't work offsite!&lt;br /&gt;
===&lt;br /&gt;
I started out using tun, but switched to tap since I didn't like the use of a /30 subnet for each PC (I need to support Windows). I found that to be wasteful and confusing.&lt;br /&gt;
&lt;br /&gt;
Then I discovered the "topology subnet" option on the server. Works with the 2.1 RCs (not 2.0), but it gives me all the advantages of tun (no bridging, performance, routing, etc) with the convenience of one (sequential) IP address per (windows) machine.&lt;br /&gt;
===&lt;br /&gt;
&lt;b&gt;What All Ports Are Rrequired By Domain Controllers And Client Computers?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Active Directory communication takes place using several ports. These ports are required by both client computers and Domain Controllers. As an example, when a client computer tries to find a domain controller it always sends a DNS Query over Port 53 to find the name of the domain controller in the domain.&lt;br /&gt;
&lt;br /&gt;
The following is the list of services and their ports used for Active Directory communication:&lt;br /&gt;
&lt;br /&gt;
UDP Port 88 for Kerberos authentication&lt;br /&gt;
UDP and TCP Port 135 for domain controllers-to-domain controller and client to domain controller operations.&lt;br /&gt;
TCP Port 139 and UDP 138 for File Replication Service between domain controllers.&lt;br /&gt;
TCP and UDP Port 389 for LDAP to handle normal queries from client computers to the domain controllers.&lt;br /&gt;
TCP and UDP Port 445 for File Replication Service&lt;br /&gt;
TCP and UDP Port 464 for Kerberos Password Change&lt;br /&gt;
TCP Port 3268 and 3269 for Global Catalog from client to domain controller.&lt;br /&gt;
TCP and UDP Port 53 for DNS from client to domain controller and domain controller to domain controller.&lt;br /&gt;
Opening above ports in Firewall between client computers and domain controllers, or between domain controllers, will enable Active Directory to function properly.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.windowsnetworking.com/kbase/WindowsTips/Windows2000/AdminTips/ActiveDirectory/WhatAllPortsAreRrequiredByDomainControllersAndClientComputers.html"&gt;http://www.windowsnetworking.com/kbase/WindowsTips/Windows2000/AdminTips/ActiveDirectory/WhatAllPortsAreRrequiredByDomainControllersAndClientComputers.html&lt;/a&gt;&lt;br /&gt;
===&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/12/set-up-openvpn-server-on-freebsd.html"&gt;http://gala4th.blogspot.com/2011/12/set-up-openvpn-server-on-freebsd.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://kuapp.com/2010/07/01/openvpn-with-freebsd-pf-and-windows-xp.html"&gt;http://kuapp.com/2010/07/01/openvpn-with-freebsd-pf-and-windows-xp.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.secure-computing.net/wiki/index.php/FreeBSD_OpenVPN_Server/Routed"&gt;http://www.secure-computing.net/wiki/index.php/FreeBSD_OpenVPN_Server/Routed&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/TUN/TAP"&gt;http://en.wikipedia.org/wiki/TUN/TAP&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://openvpn.net/archive/openvpn-users/2007-02/msg00184.html"&gt;http://openvpn.net/archive/openvpn-users/2007-02/msg00184.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://serverfault.com/questions/21157/should-i-use-tap-or-tun-for-openvpn"&gt;http://serverfault.com/questions/21157/should-i-use-tap-or-tun-for-openvpn&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://forums.freebsd.org/showthread.php?t=15213"&gt;http://forums.freebsd.org/showthread.php?t=15213&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/OpenVPN"&gt;http://en.wikipedia.org/wiki/OpenVPN&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-6254591364048473596?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/Nqg5Ja6JERE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/6254591364048473596/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=6254591364048473596" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/6254591364048473596?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/6254591364048473596?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/Nqg5Ja6JERE/set-up-openvpn-server-on-freebsd.html" title="Set up OpenVPN server on FreeBSD running PF packet filter firewall and run VPN client on Windows 7 and FreeBSD 8.2" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2011/12/set-up-openvpn-server-on-freebsd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04AQ309fCp7ImA9WhRUF0k.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-7924001639249124811</id><published>2012-01-28T03:25:00.000-08:00</published><updated>2012-01-28T03:25:42.364-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-28T03:25:42.364-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ToDo" /><title>Resolutions for 2012</title><content type="html">[] C&lt;br /&gt;
&lt;br /&gt;
[] gcc, gdb, automake, autoconf&lt;br /&gt;
&lt;br /&gt;
[] LLVM, clang, LLDB, OpenCL, KLEE&lt;br /&gt;
&lt;br /&gt;
[] Git&lt;br /&gt;
&lt;br /&gt;
[] Python&lt;br /&gt;
&lt;br /&gt;
[] PostgreSQL&lt;br /&gt;
&lt;br /&gt;
[] Dtrace&lt;br /&gt;
&lt;br /&gt;
[] ZFS&lt;br /&gt;
&lt;br /&gt;
[] RAID&lt;br /&gt;
&lt;br /&gt;
[] English&lt;br /&gt;
&lt;br /&gt;
[] NFS&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-7924001639249124811?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/YBV7w9AO1Hk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/7924001639249124811/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=7924001639249124811" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/7924001639249124811?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/7924001639249124811?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/YBV7w9AO1Hk/resolutions-2012.html" title="Resolutions for 2012" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/resolutions-2012.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08BQnc6cSp7ImA9WhRUFk0.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-5731618704047788942</id><published>2012-01-26T10:17:00.001-08:00</published><updated>2012-01-26T10:17:33.919-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-26T10:17:33.919-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Revision Control" /><title>remove old svn revisons history</title><content type="html">Say you have 1000 revisions and you want to shrink to only have the revisions from r950-r1000. You can do the following:&lt;br /&gt;
&lt;br /&gt;
svnadmin dump /path/to/current/repo -r950:1000 &gt; small_svn.dump&lt;br /&gt;
svnadmin create /path/to/new/repo&lt;br /&gt;
svnadmin load /path/to/new/repo &lt; small_svn.dump

&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/4350145/how-to-remove-old-svn-revisons"&gt;http://stackoverflow.com/questions/4350145/how-to-remove-old-svn-revisons&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-5731618704047788942?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/5Z0csI--yTU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/5731618704047788942/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=5731618704047788942" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5731618704047788942?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/5731618704047788942?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/5Z0csI--yTU/remove-old-svn-revisons-history.html" title="remove old svn revisons history" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/remove-old-svn-revisons-history.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkICQHozeip7ImA9WhRUFk0.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-4904320967481904083</id><published>2012-01-26T09:56:00.001-08:00</published><updated>2012-01-26T09:56:01.482-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-26T09:56:01.482-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MySQL" /><title>mysqldump read password from file for crontab</title><content type="html">mysqldump read password from file for crontab&lt;br /&gt;
&lt;br /&gt;
# vim ~/.my.cnf&lt;br /&gt;
&lt;br /&gt;
[client]&lt;br /&gt;
user = root&lt;br /&gt;
password = mypassword&lt;br /&gt;
&lt;br /&gt;
[mysqldump]&lt;br /&gt;
user = root&lt;br /&gt;
password = mypassword&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt;&lt;br /&gt;
[client] section is for "mysql" command.&lt;br /&gt;
[mysqldump] section is for "mysqldump" command.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make sure no other people can read .my.cnf file:&lt;/b&gt;&lt;br /&gt;
# chmod 400 ~/.my.cnf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Following two commands work:&lt;/b&gt;&lt;br /&gt;
# mysql --defaults-file=/root/.my.cnf&lt;br /&gt;
# mysqldump --defaults-file=/root/.my.cnf db_name &gt; db_name.sql&lt;br /&gt;
&lt;br /&gt;
or simply:&lt;br /&gt;
# mysql&lt;br /&gt;
# mysqldump db_name &gt; db_name.sql&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-4904320967481904083?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/gbGUSt_T10s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/4904320967481904083/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=4904320967481904083" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/4904320967481904083?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/4904320967481904083?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/gbGUSt_T10s/mysqldump-read-password-from-file-for.html" title="mysqldump read password from file for crontab" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/mysqldump-read-password-from-file-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08EQH8_eyp7ImA9WhRUFU8.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-2725163750717003819</id><published>2012-01-25T12:03:00.000-08:00</published><updated>2012-01-25T12:03:21.143-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-25T12:03:21.143-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apache" /><category scheme="http://www.blogger.com/atom/ns#" term="Nginx" /><title>disable PHP script execution in upload attachment directory</title><content type="html">disable PHP script execution in upload attachment directory&lt;br /&gt;
&lt;br /&gt;
// Apache&lt;br /&gt;
&lt;pre&gt;&amp;lt;Directory /website/attachments&amp;gt;
  php_flag engine off 
&amp;lt;/Directory&amp;gt;
&lt;/pre&gt;// Nginx&lt;br /&gt;
&lt;pre&gt;location /sites/default/files/ { 
  location ~ .*\.(php)?$
  { 
    deny all; 
  }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-2725163750717003819?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/VvODCjO4blc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/2725163750717003819/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=2725163750717003819" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/2725163750717003819?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/2725163750717003819?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/VvODCjO4blc/disable-php-script-execution-in-upload.html" title="disable PHP script execution in upload attachment directory" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/disable-php-script-execution-in-upload.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUNR3s7cCp7ImA9WhRUFE4.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-3515489631209610460</id><published>2012-01-24T11:28:00.000-08:00</published><updated>2012-01-24T11:28:16.508-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-24T11:28:16.508-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><category scheme="http://www.blogger.com/atom/ns#" term="Load Balancing" /><title>Multiple default routes gateways with two different ISP ipfw PF setfib load balancing</title><content type="html">Multiple default routes gateways with two different ISP ipfw PF setfib load balancing&lt;br /&gt;
&lt;br /&gt;
Thanks to phoenix help I was able to setup multiple default routes, or a default route per network/interface to be precise, in Debian/Linux it is as simple as that:&lt;br /&gt;
&lt;br /&gt;
# cat /etc/network/interfaces&lt;br /&gt;
&lt;pre&gt;iface eth0 inet static
    address 10.0.0.2
    netmask 255.255.255.252
    gateway 10.0.0.1

iface eth1 inet static
    address 20.0.0.2
    netmask 255.255.255.252
    gateway 20.0.0.1
&lt;/pre&gt;&lt;br /&gt;
That would be example topology (but more than 2 interfaces is also possible).&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;ISP NETWORK 0                   ISP NETWORK 1
         \                          /
          \                        /
           \                      /
          ROUTER 0            ROUTER 1
          10.0.0.1/30         20.0.0.1/30
              \                  /
        +------\----------------/------+
        |       \              /       |
        |       wan0          wan1     |
        |    10.0.0.2     20.0.0.2     |
        |                              |
        |   FREEBSD (Firewall Router)  |
        |                              |
        |             dmz0             |
        |       192.168.0.1/24         |
        |       192.168.0.2/24         |
        +------------------------------+
                       |
                   +--------+
                   | switch +
                   +--------+
                       |
                      /
               ______/
              /
    +--------/-----+
    |       /      |
    |      lan0    |
    |  192.168.0.3 |
    |  192.168.0.4 |
    |              |
    | Web Server 0 |
    +--------------+
&lt;/pre&gt;&lt;br /&gt;
Now, You can not use the 'casual' &lt;b&gt;defaultrouter="X"&lt;/b&gt; cause it will be only for one network.&lt;br /&gt;
&lt;br /&gt;
We will have to use &lt;b&gt;setfib(1)&lt;/b&gt; to create two (or more) separete routing tables per network/interface.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; FIB (Forward Information Base, synonym for a routing table here)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Add these lines to /boot/loader.conf file:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# vim /boot/loader.conf&lt;br /&gt;
### select one of following firewalls to enable.&lt;br /&gt;
#ipfw_load="YES"                  # Firewall&lt;br /&gt;
pf_load="YES"                    # packet filter&lt;br /&gt;
pflog_load="YES"                    # packet filter log&lt;br /&gt;
&lt;br /&gt;
### set number of routing tables to support.&lt;br /&gt;
net.fibs=2&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; to view a list of options: cat /boot/defaults/loader.conf.&lt;br /&gt;
&lt;br /&gt;
It will unfortunately require kernel recompile, but its not as that hard:&lt;br /&gt;
&lt;br /&gt;
# cd /usr/src/sys/`uname -m`/conf&lt;br /&gt;
# cp GENERIC MYKERNEL8.2&lt;br /&gt;
&lt;br /&gt;
# vim MYKERNEL8.2&lt;br /&gt;
options  ROUTETABLES=2  # max 16. 1 is back compatible.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; to view a list of available options:&lt;br /&gt;
# cat /usr/src/sys/conf/NOTES | grep ROUTETABLES&lt;br /&gt;
options  ROUTETABLES=2  # max 16. 1 is back compatible.&lt;br /&gt;
&lt;br /&gt;
# cat /usr/src/sys/`uname -m`/conf/DEFAULTS&lt;br /&gt;
&lt;br /&gt;
# cd /usr/src&lt;br /&gt;
# make buildkernel KERNCONF=MYKERNEL8.2&lt;br /&gt;
# make installkernel KERNCONF=MYKERNEL8.2&lt;br /&gt;
&lt;br /&gt;
# sync ; reboot&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; if the system could not boot properly, press any keys other than enter key when you see the count down number. and type following at boot: prompt:&lt;br /&gt;
boot: unload&lt;br /&gt;
boot: /kernel.old&lt;br /&gt;
&lt;a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/boot-blocks.html"&gt;http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/boot-blocks.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Remove the files generated during recompiling the kernel. &lt;br /&gt;
# rm -rf /usr/obj/usr/src/sys/MYKERNEL8.2&lt;br /&gt;
&lt;br /&gt;
After the kernel has been built and rebooted the different routing tables can be accessed as shown in the setfib(1) man page by issuing command setfib 0 netstat -rn. 0 is the default routing table.&lt;br /&gt;
&lt;br /&gt;
After this one has to create the second routing table by prepending every route add command with setfib 1 route add… e.g:&lt;br /&gt;
&lt;br /&gt;
# setfib 0 /sbin/route add -net default 10.0.0.1&lt;br /&gt;
# setfib 1 /sbin/route add -net default 20.0.0.1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; with packet filter one can control how the routing table is selected by using rtable option but it should be noted that this selection can only be done on the input of the packets as the routing decision is done at the input not at the output.&lt;br /&gt;
&lt;br /&gt;
# vi /etc/rc.conf&lt;br /&gt;
### WAN interfaces. You do not need to set defaultrouter="XXX" here.&lt;br /&gt;
ifconfig_wan0="inet 10.0.0.2/32"&lt;br /&gt;
ifconfig_wan1="inet 20.0.0.2/32"&lt;br /&gt;
&lt;br /&gt;
### Note: commented out for multiple WAN routes setup. Routes will be added in /etc/rc.local file.&lt;br /&gt;
#defaultrouter="10.0.0.1"&lt;br /&gt;
&lt;br /&gt;
### LAN static route&lt;br /&gt;
#static_routes="lan"&lt;br /&gt;
#route_lan="-net 192.168.50.0/24 192.168.0.11"&lt;br /&gt;
&lt;br /&gt;
### PF (Packet Filter Firewall)&lt;br /&gt;
pf_enable="YES"&lt;br /&gt;
pf_rules="/etc/pf.conf"&lt;br /&gt;
pf_flags=""&lt;br /&gt;
pflog_enable="YES"&lt;br /&gt;
pflog_logfile="/var/log/pf.log"&lt;br /&gt;
pflog_flags=""&lt;br /&gt;
&lt;br /&gt;
### Enable as LAN gateway&lt;br /&gt;
gateway_enable="YES"&lt;br /&gt;
&lt;br /&gt;
All the rest configuration resides in /etc/rc.local file:&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.local&lt;br /&gt;
### add first routing table for first interface for first ISP network.&lt;br /&gt;
/usr/sbin/setfib 0 /sbin/route delete default&lt;br /&gt;
/usr/sbin/setfib 0 /sbin/route add    default 10.0.0.1&lt;br /&gt;
&lt;br /&gt;
### add second routing table for second interface for second ISP network.&lt;br /&gt;
/usr/sbin/setfib 1 /sbin/route delete default&lt;br /&gt;
/usr/sbin/setfib 1 /sbin/route add    default 20.0.0.1&lt;br /&gt;
&lt;br /&gt;
### assing route tables to interfaces&lt;br /&gt;
### Note: uncomment following lines if you are using ipfw. Leave it if you are using PF.&lt;br /&gt;
###&lt;br /&gt;
#ipfw -f flush&lt;br /&gt;
#ipfw add allow    ip from any to any via lo0&lt;br /&gt;
#ipfw add setfib 0 ip from any to any via wan0&lt;br /&gt;
#ipfw add setfib 1 ip from any to any via wan1&lt;br /&gt;
#ipfw add allow    ip from any to any&lt;br /&gt;
&lt;br /&gt;
These would be handy for restarting:&lt;br /&gt;
# /etc/rc.d/netif restart &amp;amp;&amp;amp; /etc/rc.d/routing restart&lt;br /&gt;
# /etc/rc.d/local restart&lt;br /&gt;
# pfctl -f /etc/pf.conf&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;View the fib:&lt;/b&gt;&lt;br /&gt;
# sysctl -a | grep fib&lt;br /&gt;
net.my_fibnum: 0&lt;br /&gt;
net.add_addr_allfibs: 1&lt;br /&gt;
net.fibs: 2&lt;br /&gt;
&lt;br /&gt;
View the default route of each routing table:&lt;br /&gt;
&lt;br /&gt;
# setfib 0 netstat -rn&lt;br /&gt;
# setfib 1 netstat -rn&lt;br /&gt;
&lt;br /&gt;
Try to ping:&lt;br /&gt;
# setfib 0 ping google.com&lt;br /&gt;
# setfib 1 ping google.com&lt;br /&gt;
&lt;br /&gt;
===============================================================&lt;br /&gt;
pf.conf&lt;br /&gt;
&lt;br /&gt;
Looking for something like this?&lt;br /&gt;
&lt;br /&gt;
# man 1 setfib&lt;br /&gt;
# man 2 setfib&lt;br /&gt;
&lt;br /&gt;
And pf.conf(5) has the route-to and reply-to directives, of course.&lt;br /&gt;
&lt;br /&gt;
# man 5 pf.conf | less +/rtable&lt;br /&gt;
# man 5 pf.conf | less +/route-to&lt;br /&gt;
# man 5 pf.conf | less +/reply-to&lt;br /&gt;
&lt;br /&gt;
# vim /etc/pf.conf&lt;br /&gt;
### [VARIABLES]&lt;br /&gt;
wan_if0 = "wan0"&lt;br /&gt;
wan_if1 = "wan1"&lt;br /&gt;
dmz_if0 = "dmz0"&lt;br /&gt;
www0_ip0 = "192.168.0.3"&lt;br /&gt;
www0_ip1 = "192.168.0.4"&lt;br /&gt;
&lt;br /&gt;
##########################&lt;br /&gt;
##### TABLES - A structure used to hold lists of IP addresses.&lt;br /&gt;
##########################&lt;br /&gt;
table &amp;lt;blocked_ip&amp;gt; persist file "/etc/pf-blocked_ip"&lt;br /&gt;
&lt;br /&gt;
### [NAT]&lt;br /&gt;
nat on $wan_if0 from $dmz_if0/24 to any -&amp;gt; $wan_if0&lt;br /&gt;
nat on $wan_if1 from $dmz_if0/24 to any -&amp;gt; $wan_if1&lt;br /&gt;
&lt;br /&gt;
### [HTTP] RDR Outside to DMZ&lt;br /&gt;
rdr on $wan_if0 proto tcp from any to $wan_if0 port 80 -&amp;gt; $www0_ip0&lt;br /&gt;
rdr on $wan_if1 proto tcp from any to $wan_if1 port 80 -&amp;gt; $www0_ip1&lt;br /&gt;
&lt;br /&gt;
### [HTTP] outside to router&lt;br /&gt;
pass in quick on $wan_if0 proto {tcp} from any to $wan_if0 port 80 rtable 0&lt;br /&gt;
pass in quick on $wan_if1 proto {tcp} from any to $wan_if1 port 80 rtable 1&lt;br /&gt;
&lt;br /&gt;
### [HTTP] router to dmz&lt;br /&gt;
pass out quick log on $dmz_if0 proto {tcp} from any to $www0_ip0 port 80 rtable 0&lt;br /&gt;
pass out quick log on $dmz_if0 proto {tcp} from any to $www0_ip1 port 80 rtable 1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Troubleshooting&lt;/b&gt;&lt;br /&gt;
dump traffic on a network, see packets that match a certain port&lt;br /&gt;
# tcpdump -ni re0 port 53&lt;br /&gt;
&lt;br /&gt;
You may also want to limit tcpdump to just show icmp:&lt;br /&gt;
# tcpdump -ni re0 icmp&lt;br /&gt;
&lt;br /&gt;
Or just to/from a certain host:&lt;br /&gt;
# tcpdump -ni re0 icmp host 172.16.70.12&lt;br /&gt;
&lt;br /&gt;
Reading a PF (packet filter) log file&lt;br /&gt;
&lt;br /&gt;
The log file written by pflogd is in binary format and cannot be read using a text editor. Tcpdump must be used to view the log.&lt;br /&gt;
&lt;br /&gt;
To view the log file:&lt;br /&gt;
&lt;br /&gt;
# tcpdump -n -e -ttt -r /var/log/pf.log&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; that using tcpdump(8) to watch the pflog file does not give a real time display. A real time display of logged packets is achieved by using the pflog0 interface:&lt;br /&gt;
&lt;br /&gt;
# ifconfig | grep pflog&lt;br /&gt;
# tcpdump -n -e -ttt -i pflog0&lt;br /&gt;
&lt;br /&gt;
Filtering Log Output&lt;br /&gt;
&lt;br /&gt;
Because pflogd logs in tcpdump binary format, the full range of tcpdump features can be used when reviewing the logs. For example, to only see packets that match a certain port:&lt;br /&gt;
&lt;br /&gt;
# tcpdump -n -e -ttt -r /var/log/pf.log port 80&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/12/set-up-pf-packet-filter-on-freebsd.html"&gt;set up PF (packet filter) firewall on FreeBSD 8.1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Other Solution:&lt;/b&gt;&lt;br /&gt;
# man lagg - link aggregation and link failover interface.&lt;br /&gt;
# man ngctl - netgraph control utility.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-aggregation.html"&gt;http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-aggregation.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.freebsd.org/cgi/man.cgi?query=lagg&amp;sektion=4"&gt;http://www.freebsd.org/cgi/man.cgi?query=lagg&amp;sektion=4&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://scratching.psybermonkey.net/2009/06/freebsd-combine-2-or-more-nic-using.html"&gt;http://scratching.psybermonkey.net/2009/06/freebsd-combine-2-or-more-nic-using.html&lt;/a&gt;&lt;br /&gt;
===============================================================&lt;br /&gt;
Just a quick note, if doing this on a router with a single internal interface.&lt;br /&gt;
&lt;br /&gt;
Traffic originating on the local network will go out the default route of FIB 0.&lt;br /&gt;
&lt;br /&gt;
Only traffic coming in on the second public interface will go out the same interface.&lt;br /&gt;
&lt;br /&gt;
IOW, the setup above is really only useful for incoming traffic, to make sure that it goes back out the correct interface.&lt;br /&gt;
&lt;br /&gt;
However, a few more IPFW rules can be added to classify traffic on the internal NIC.&lt;br /&gt;
&lt;br /&gt;
It all depends on what you want to accomplish.&lt;br /&gt;
&lt;br /&gt;
Yes, its mainly for that purpose, to assign proper gateways to networks/interfaces (which is a lot more easier @ Debian in /etc/network/interfaces)&lt;br /&gt;
&lt;br /&gt;
We may even use FIB# 1 and 2 for these networks, and use FIB# 0 with other NIC as a default interface, posibilities are of course big, but I wanted to point posibility of having a gateway per network.&lt;br /&gt;
&lt;br /&gt;
http://www.daemonforums.org/showthread.php?t=4610&lt;br /&gt;
===============================================================&lt;br /&gt;
setfib selects the routing table for locally originated&lt;br /&gt;
outgoing packets. Besides locally originated packets, there&lt;br /&gt;
are packets arriving from the network and need to be forwarded.&lt;br /&gt;
These packets can be classified in a specific routing table&lt;br /&gt;
with the aid of ipfw. That's all there is. I can't think&lt;br /&gt;
of something else that needs to be thought with regard to&lt;br /&gt;
multiple routing tables.&lt;br /&gt;
&lt;br /&gt;
HTH, Nikos&lt;br /&gt;
&lt;br /&gt;
http://lists.freebsd.org/pipermail/freebsd-questions/2009-July/202462.html&lt;br /&gt;
===============================================================&lt;br /&gt;
Something has been bugging me for several years now. In that time I have usually had access to multiple WAN connections, owing to my participation in the telecom industry. However, I've never been able to get SSHD to behave the way I wanted it to. I wanted to be able to connect to the SSH daemon on my (FreBSD) router from whichever WAN connection I wanted. Unfortunately, SSHD is stuborn about always routing its response to the default gateway of the router, which breaks an SSH connection coming in from the secondary WAN connection.&lt;br /&gt;
&lt;br /&gt;
I have finally, at long last, found the solution.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Problem:&lt;/b&gt; When describing this problem to other FreeBSD users, they pretty universally assumed that I was mistaken, and that the SSH daemon would by default route its responses out the interface that the initial request had been received on. Evidently, it is uncommon to run SSHD on more than one WAN interface. At its root, this problem just boils down to the routing table. SSHD doesn't route it's responses to the interface that they were received on, it uses the routing table to determine where to send it's responses. If the request came from a local network, then it responds to the local network. If it originated from a non-local network, then it uses the default gateway. It's really that simple. There is no logic for having multiple paths to non-local networks.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Frequently Offered Solution:&lt;/b&gt; Since I use pf for my firewall, I'm frequently told to use pf's route-to and reply-to functionality to solve this problem. I have at times used route-to and reply-to extensively in my pf.conf. But route-to and reply-to do not trump the default routing table for traffic the originates or terminates on the router itself. They are useful only for traffic passing through the router. pf can only make routing decisions when a packet passes through an interface. It can try and set the reply-to interface to be the second WAN connection when an inbound SSH connection is made, but neither the SSH daemon nor the routing table on the host know or care about the routing preferences of pf.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Real Solution:&lt;/b&gt; FreeBSD has support for multiple routing tables. It's little known, and even less documented, but it does exist. Basically, you need to recompile your kernel with multiple routing table support ("options ROUTETABLES=2"), and then use the setfib program to set which routing table to use when starting another program. The syntax is similar to nice: setfib 1 route add default 192.168.1.1 would add a default route of 192.168.1.1 to the second routing table on the host. If not specified, the default routing table is 0. On FreeBSD, pf also has support for multiple routing tables with the little discussed rtable option.&lt;br /&gt;
&lt;br /&gt;
So here are the steps to solving this problem:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 1:&lt;/b&gt; Rebuild your kernel with the ROUTETABLES option set to a non-zero integer. This is how many routing tables your host will support.&lt;br /&gt;
&lt;br /&gt;
# cat /usr/src/sys/`uname -m`/conf/MYKERNEL8.2 | grep ROUTETABLES&lt;br /&gt;
options    ROUTETABLES=2        # max 16. 1 is back compatible.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 2:&lt;/b&gt; Disable the SSH daemon in your rc.conf:&lt;br /&gt;
&lt;br /&gt;
# cat /etc/rc.conf | grep ssh&lt;br /&gt;
#sshd_enable="YES" # This is now handled by /etc/rc.local&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 3:&lt;/b&gt; Create /etc/rc.local file to start multiple SSH daemons. To do this, copy the /etc/ssh/sshd_config file to several alternates, one per interface you want SSHD to listen to, and set the ListenAddress for each file to only the IP for that interface.&lt;br /&gt;
&lt;br /&gt;
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.rtable0&lt;br /&gt;
# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.rtable1&lt;br /&gt;
&lt;br /&gt;
# vim /etc/ssh/sshd_config.rtable0&lt;br /&gt;
ListenAddress 20.0.0.2&lt;br /&gt;
ListenAddress 192.168.0.1&lt;br /&gt;
&lt;br /&gt;
# vim /etc/ssh/sshd_config.rtable1&lt;br /&gt;
ListenAddress 30.0.0.2&lt;br /&gt;
ListenAddress 192.168.0.2&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; Multiple ListenAddress options are permitted.&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.local&lt;br /&gt;
### add first routing table for first interface for first ISP network.&lt;br /&gt;
/usr/sbin/setfib 0 /sbin/route delete default&lt;br /&gt;
/usr/sbin/setfib 0 /sbin/route add default 20.0.0.1&lt;br /&gt;
&lt;br /&gt;
### add second routing table for second interface for second ISP network.&lt;br /&gt;
/usr/sbin/setfib 1 /sbin/route delete default&lt;br /&gt;
/usr/sbin/setfib 1 /sbin/route add default 30.0.0.1&lt;br /&gt;
&lt;br /&gt;
### Start SSH daemons for each interface&lt;br /&gt;
/usr/sbin/setfib 0 /usr/sbin/sshd -f /etc/ssh/sshd_config.rtable0&lt;br /&gt;
/usr/sbin/setfib 1 /usr/sbin/sshd -f /etc/ssh/sshd_config.rtable1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 4:&lt;/b&gt; Add rtable awareness to your pf.conf file:&lt;br /&gt;
&lt;br /&gt;
[root@router]~ # cat /etc/pf.conf | grep rtable&lt;br /&gt;
pass in log on tun0 inet proto icmp from any to (tun0) icmp-type  rtable 0&lt;br /&gt;
pass in log on tun1 inet proto icmp from any to (tun1) icmp-type  rtable 1&lt;br /&gt;
pass in log on tun0 inet proto tcp from any to (tun0) port ssh rtable 0&lt;br /&gt;
pass in log on tun1 inet proto tcp from any to (tun1) port ssh rtable 1&lt;br /&gt;
pass in log on wan0 inet proto tcp from wan0:network to (wan0) port 22 rtable 0&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conclusion:&lt;/b&gt; Because the SSH daemon listening on tun1 is using a routing table that features the tun1 interface as the default gateway, the response will go out tun1. An inbound connection to tun0 will hit the SSH daemon listening on tun0 (which is an entirely separate process from the one listening on tun1) and uses the routing table associated with tun0, which features tun0 as the default gateway.&lt;br /&gt;
&lt;br /&gt;
In my above config it's worth pointing out that it doesn't actually matter which routing table the SSH daemon listening on the LAN interface uses, because both routing tables see the LAN network as a local one. By default on FreeBSD with multiple routing tables enabled, all local networks will still appear in all the routing tables. There is a sysctl option to disable this behavior.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;High Availability HA cluster solution for FreeBSD&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
HAST + CARP + ZFS&lt;br /&gt;
&lt;br /&gt;
HAST (Highly Available Storage) - allows to transparently store data on two physically separated machines connected over the TCP/IP network.&lt;br /&gt;
&lt;br /&gt;
CARP (Common Address Redundancy Protocol) - allows multiple hosts to share the same IP address. In some configurations, this may be used for availability or load balancing. Hosts may use separate IP addresses as well, as in the example provided here.&lt;br /&gt;
&lt;br /&gt;
# man carp&lt;br /&gt;
# man ng_one2many&lt;br /&gt;
# man lagg - link aggregation and link failover interface.&lt;br /&gt;
# man ngctl - netgraph control utility.&lt;br /&gt;
&lt;br /&gt;
http://www.freebsd.org/doc/handbook/carp.html&lt;br /&gt;
http://forums.freebsd.org/showthread.php?t=17133&lt;br /&gt;
http://blather.michaelwlucas.com/archives/241&lt;br /&gt;
===============================================================&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/10/multiple-default-routes-gateways-with.html"&gt;http://gala4th.blogspot.com/2011/10/multiple-default-routes-gateways-with.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/11/high-availability-ha-cluster-solution.html"&gt;High Availability HA cluster solution for freebsd&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.daemonforums.org/showthread.php?t=4610"&gt;http://www.daemonforums.org/showthread.php?t=4610&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://freebsd-forums.liquidneon.com/showthread.php?t=20166"&gt;http://freebsd-forums.liquidneon.com/showthread.php?t=20166&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.mmacleod.ca/blog/2011/06/source-based-routing-with-freebsd-using-multiple-routing-table/"&gt;http://www.mmacleod.ca/blog/2011/06/source-based-routing-with-freebsd-using-multiple-routing-table/&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.melen.org/u/jan/wp/?p=102"&gt;http://www.melen.org/u/jan/wp/?p=102&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/12/set-up-pf-packet-filter-on-freebsd.html"&gt;http://gala4th.blogspot.com/2010/12/set-up-pf-packet-filter-on-freebsd.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://forums.freebsd.org/showthread.php?t=19047"&gt;Running PF &amp;amp; IPFW Together&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/12/prevent-resolvconf-being-overwritten-by.html"&gt;Prevent default gateway route and resolv.conf being overwritten by DHCP&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-3515489631209610460?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/NlSsirvssjc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/3515489631209610460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=3515489631209610460" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/3515489631209610460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/3515489631209610460?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/NlSsirvssjc/multiple-default-routes-gateways-with.html" title="Multiple default routes gateways with two different ISP ipfw PF setfib load balancing" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2011/10/multiple-default-routes-gateways-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AEQX45cCp7ImA9WhRUFE8.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-6197439687331458537</id><published>2012-01-24T09:21:00.000-08:00</published><updated>2012-01-24T09:21:40.028-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-24T09:21:40.028-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><category scheme="http://www.blogger.com/atom/ns#" term="command" /><category scheme="http://www.blogger.com/atom/ns#" term="Mail" /><title>kill sendmail processes and clean up mail queue mailq</title><content type="html">kill sendmail processes and clean up mail queue mailq&lt;br /&gt;
&lt;br /&gt;
# ps auxww | grep 'sendmail: ./' | awk '{print $2}' | xargs kill&lt;br /&gt;
# rm /var/spool/mqueue/*&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-6197439687331458537?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/iQiL5vljsHo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/6197439687331458537/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=6197439687331458537" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/6197439687331458537?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/6197439687331458537?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/iQiL5vljsHo/kill-sendmail-processes-and-clean-up.html" title="kill sendmail processes and clean up mail queue mailq" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2011/11/kill-sendmail-processes-and-clean-up.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MARXY5eSp7ImA9WhRUE0s.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-3408450685267452694</id><published>2012-01-23T15:30:00.000-08:00</published><updated>2012-01-23T15:30:44.821-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-23T15:30:44.821-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><category scheme="http://www.blogger.com/atom/ns#" term="Unix-like Tips" /><title>Check if a file is opened in use or locked by another process</title><content type="html">The PHP flock() function is good when the file locking method is used the same way by all programs that will lock the file.&lt;br /&gt;
&lt;br /&gt;
However, you can't check if any process in the system is actually using the file or not. If you for example are monitoring an incoming ftp folder, you don't want to start processing a file until the file is completely tranferred (i.e. wait until the ftp daemon is no longer having the file open).&lt;br /&gt;
&lt;br /&gt;
The following code illustrates how the command lsof (Linux) or fstat (FreeBSD) can be used for the purpose: &lt;br /&gt;
&lt;br /&gt;
lsof on Linux:&lt;br /&gt;
&lt;pre class="php" name="code"&gt;&amp;lt;?php
$filename = "locktest.txt";
$directory = ".";
while (1) {
        $result = exec("lsof +D $directory | grep -c -i $filename");
        if ($result == "0") {
                echo "$directory/$filename is NOT open ($result)\n";
        } else {
                echo "$directory/$filename IS OPEN ($result)\n";
        }
        sleep(1);
};
?&gt;&lt;/pre&gt;&lt;br /&gt;
fstat on FreeBSD:&lt;br /&gt;
&lt;pre class="php" name="code"&gt;&amp;lt;?php
$out = exec('fstat test.pdf | wc -l');
$out = trim($out);

if ($out == 1) {
  echo 'not in use' . PHP_EOL;
}
else {
  echo 'in use' . PHP_EOL;
}
?&gt;&lt;/pre&gt;&lt;br /&gt;
test.sh:&lt;br /&gt;
&lt;pre class="php" name="code"&gt;#!/bin/sh

dir="/home/backup/"

find "${dir}" -type f | while read file
do
  isFileInUse=`fstat "${file}" | grep -c "${file}"`

  #echo "${isFileInUse}"

  if [ "${isFileInUse}"  = "0" ]; then
    #echo ${isFileInUse}
    echo "File is Not in use. ${file}"
  else
    echo "File is in use. ${file}"
  fi
done
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
http://nerdia.net/2011/01/17/check-if-a-file-is-open-by-another-process-in-php-linuxunix/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-3408450685267452694?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/yd6rB4-zoQY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/3408450685267452694/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=3408450685267452694" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/3408450685267452694?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/3408450685267452694?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/yd6rB4-zoQY/check-if-file-is-opened-in-use-by.html" title="Check if a file is opened in use or locked by another process" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2011/06/check-if-file-is-opened-in-use-by.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEESXk9fyp7ImA9WhRUE0g.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-3666003290733236939</id><published>2012-01-23T13:03:00.000-08:00</published><updated>2012-01-23T13:03:28.767-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-23T13:03:28.767-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><title>Install Samba on FreeBSD 8.2</title><content type="html">Install Samba on FreeBSD 8.2&lt;br /&gt;
&lt;br /&gt;
root@bmw0 [/root] # cd /usr/ports/net/samba36; make install clean&lt;br /&gt;
&lt;br /&gt;
Edit smb.conf&lt;br /&gt;
&lt;br /&gt;
root@bmw0 [/root] # vi /usr/local/etc/smb.conf&lt;br /&gt;
security = user&lt;br /&gt;
hosts allow = 192.168.100. 192.168.200.168 127.&lt;br /&gt;
load printers = no&lt;br /&gt;
&lt;br /&gt;
[syncdb]&lt;br /&gt;
comment = hmm&lt;br /&gt;
path = /usr/local/www/apache22/data/syncdb&lt;br /&gt;
valid users = smb_user0&lt;br /&gt;
public = no&lt;br /&gt;
writable = yes&lt;br /&gt;
printable = no&lt;br /&gt;
create mask = 0600&lt;br /&gt;
directory mask = 0700&lt;br /&gt;
; write list = @staff&lt;br /&gt;
&lt;br /&gt;
Add a user called "smb_user0"&lt;br /&gt;
root@bmw0 [/root] # pw useradd -n smb_user0 -s /sbin/nologin -w no -d /home/smb_user0 -c "Samaba User0" -m&lt;br /&gt;
&lt;br /&gt;
Adding users to samba&lt;br /&gt;
root@bmw0 [/root] # /usr/local/bin/pdbedit -a smb_user0&lt;br /&gt;
or&lt;br /&gt;
root@bmw0 [/root] # smbpasswd -a smb_user0&lt;br /&gt;
&lt;br /&gt;
List user&lt;br /&gt;
root@bmw0 [/root] # /usr/local/bin/pdbedit -L&lt;br /&gt;
&lt;br /&gt;
Edit rc.conf&lt;br /&gt;
root@bmw0 [/root] # vi /etc/rc.conf&lt;br /&gt;
### Samba&lt;br /&gt;
samba_enable="YES"&lt;br /&gt;
#nmbd_enable="YES"&lt;br /&gt;
#smbd_enable="YES"&lt;br /&gt;
winbindd_enable="YES"&lt;br /&gt;
&lt;br /&gt;
Start Samba&lt;br /&gt;
root@bmw0 [/root] # /usr/local/etc/rc.d/samba start&lt;br /&gt;
root    56804  0.2  0.7 39668 14484  ??  Ss    5:15PM   0:00.04 /usr/local/sbin/smbd -D -s /usr/local/etc/smb.conf&lt;br /&gt;
root    56807  0.2  0.7 39752 14564  ??  S     5:15PM   0:00.00 /usr/local/sbin/smbd -D -s /usr/local/etc/smb.conf&lt;br /&gt;
root    56800  0.0  0.4 29696  7464  ??  Ss    5:15PM   0:00.01 /usr/local/sbin/nmbd -D -s /usr/local/etc/smb.conf&lt;br /&gt;
&lt;br /&gt;
Check to see if samba is running&lt;br /&gt;
root@bmw0 [/root] # ps -auwxx | egrep '[sn]mbd|winbindd'&lt;br /&gt;
&lt;br /&gt;
Test samba using smbclient&lt;br /&gt;
root@bmw0 [/root] # /usr/local/bin/smbclient -U smb_user0 \\\\localhost\\smb_user0&lt;br /&gt;
or&lt;br /&gt;
root@bmw0 [/root] # /usr/local/bin/smbclient -U smb_user0 //localhost/smb_user0&lt;br /&gt;
&lt;br /&gt;
Edit ipfw.rules&lt;br /&gt;
root@bmw0 [/root] # vi /usr/local/etc/ipfw.rules&lt;br /&gt;
### samba&lt;br /&gt;
$IPF 260 allow tcp from 192.168.100.0/24 to any 139 in&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2012/01/install-samba-on-freebsd-82.html"&gt;http://gala4th.blogspot.com/2012/01/install-samba-on-freebsd-82.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-3666003290733236939?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/iQxaSZAhniQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/3666003290733236939/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=3666003290733236939" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/3666003290733236939?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/3666003290733236939?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/iQxaSZAhniQ/install-samba-on-freebsd-82.html" title="Install Samba on FreeBSD 8.2" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/install-samba-on-freebsd-82.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcHQ3szcCp7ImA9WhRUEEQ.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-9217762294454936062</id><published>2012-01-20T12:07:00.000-08:00</published><updated>2012-01-20T12:07:12.588-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-20T12:07:12.588-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><title>set up PF (packet filter) firewall on FreeBSD 8.2</title><content type="html">set up PF (packet filter) firewall on FreeBSD 8.2&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Network Structure&lt;/span&gt;&lt;br /&gt;
Outside World &amp;lt;-----&amp;gt; &lt;a href="http://www.openbsd.org/faq/pf/index.html"&gt;PF&lt;/a&gt; on &lt;a href="http://www.freebsd.org/"&gt;FreeBSD 8.1&lt;/a&gt; as a &lt;a href="http://en.wikipedia.org/wiki/Router"&gt;router&lt;/a&gt; &amp;lt;-----&amp;gt; &lt;a href="http://en.wikipedia.org/wiki/DMZ_(computing)"&gt;DMZ&lt;/a&gt; network (more FreeBSD boxes)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Quick Notes&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
[] "pfctl -e" or "pfctl -d" can be used to enable and disable PF respectively. Note that this just enables or disables PF, it doesn't actually load a ruleset. The ruleset must be loaded separately, either before or after PF is enabled. To load the pf.conf ruleset file, run "pfctl -f /etc/pf.conf".&lt;br /&gt;
&lt;br /&gt;
[] Filter rules are evaluated in sequential order, first to last. Unless the packet matches a rule containing the quick keyword, the packet will be evaluated against all filter rules before the final action is taken.&lt;br /&gt;
&lt;br /&gt;
[] The last rule to match is the "winner" and will dictate what action to take on the packet.&lt;br /&gt;
&lt;br /&gt;
[] There is an implicit pass all at the beginning of a filtering ruleset meaning that if a packet does not match any filter rule the resulting action will be pass.&lt;br /&gt;
&lt;br /&gt;
[] The keyword &lt;b&gt;any&lt;/b&gt; meaning all addresses.&lt;br /&gt;
&lt;br /&gt;
[] The keyword &lt;b&gt;all&lt;/b&gt; which is short for from any to any.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit /boot/loader.conf:&lt;/b&gt;&lt;br /&gt;
# vim /boot/loader.conf&lt;br /&gt;
pf_load="YES"                    # packet filter&lt;br /&gt;
pflog_load="YES"                    # packet filter log&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Edit /etc/rc.conf&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;### LAN&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;ifconfig_xl0="inet 192.168.3.1 netmask 255.255.255.0"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;### WAN&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;ifconfig_re0="inet 219.17.112.243 netmask 255.255.255.192"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;### WAN - extra IP addresses&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;### Note: the netmask of extra IP addresses must be 255.255.255.255&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;ifconfig_re0_alias0="inet 219.17.112.244 netmask 255.255.255.255"&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;ifconfig_re0_alias1="inet 219.17.112.245 netmask 255.255.255.255"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;### Default Route&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;defaultrouter="219.17.112.193"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;### LAN static route&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;static_routes="lan"&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;route_lan="-net 192.168.5.0/24 192.168.100.9"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;### enable PF (Packet Filter Firewall)&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;pf_enable="YES"&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;pf_rules="/etc/pf.conf"&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;pf_flags=""&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;pflog_enable="YES"&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;pflog_logfile="/var/log/pf.log"&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;pflog_flags=""&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;### enable as LAN gateway.&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;### You must enable this if you want to do NAT (network address translation).&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;gateway_enable="YES"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;### FTP-Proxy.&lt;br /&gt;
### Note: add these two lines to allow people to connect to your FTP server (192.168.100.8) behind NAT.&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;ftpproxy_enable="YES"&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;ftpproxy_flags="-R 192.168.100.8"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; Since NAT is almost always used on routers and network gateways, it will probably be necessary to enable IP forwarding so that packets can travel between network interfaces on the OpenBSD machine. IP forwarding is enabled using the sysctl(3) mechanism&lt;br /&gt;
&lt;br /&gt;
On FreeBSD, setting gateway_enable="YES" in /etc/rc.conf will automatically turn on net.inet.ip.forwarding=1. You can check this by running:&lt;br /&gt;
&lt;br /&gt;
# sysctl net.inet.ip.forwarding&lt;br /&gt;
net.inet.ip.forwarding: 1&lt;br /&gt;
&lt;br /&gt;
If you are using OpenBSD, you can run follow command:&lt;br /&gt;
&lt;br /&gt;
# sysctl net.inet.ip.forwarding=1&lt;br /&gt;
# sysctl net.inet6.ip6.forwarding=1 (if using IPv6) &lt;br /&gt;
&lt;br /&gt;
To make this change permanent, the following lines should be added to /etc/sysctl.conf (on OpenBSD. No need on FreeBSD): &lt;br /&gt;
&lt;br /&gt;
net.inet.ip.forwarding=1&lt;br /&gt;
net.inet6.ip6.forwarding=1 &lt;br /&gt;
&lt;br /&gt;
These lines are present but commented out (prefixed with a #) in the default install. Remove the # and save the file. IP forwarding will be enabled when the machine is rebooted. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create a file for later use:&lt;/b&gt;&lt;br /&gt;
# touch /etc/pf-blocked_ip&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Edit /etc/pf.conf&lt;/span&gt;&lt;br /&gt;
root@fw1 [/root] # cat /etc/pf.conf&lt;br /&gt;
&lt;span style="color: blue;"&gt;&lt;br /&gt;
##########################&lt;br /&gt;
##### MACROS - User-defined variables that can hold IP addresses, interface names, etc.&lt;br /&gt;
##########################&lt;br /&gt;
wan_if="re0"&lt;br /&gt;
dmz_if="xl0"&lt;br /&gt;
#lan_if=""&lt;br /&gt;
&lt;br /&gt;
icmp_types = "{echoreq echorep unreach}"&lt;br /&gt;
#icmp_types = "{echoreq}"&lt;br /&gt;
&lt;br /&gt;
tcp_services = "{ssh smtp domain http https ntp nicname}"&lt;br /&gt;
&lt;br /&gt;
udp_services = "{domain ntp}"&lt;br /&gt;
&lt;br /&gt;
allow_ssh_ip = "{219.17.152.199 224.1.1.1}"&lt;br /&gt;
&lt;br /&gt;
dmz_www_ip = "192.168.100.5"&lt;br /&gt;
&lt;br /&gt;
dmz_sql_ip = "192.168.100.6"&lt;br /&gt;
&lt;br /&gt;
dmz_svn_ip = "192.168.100.7"&lt;br /&gt;
&lt;br /&gt;
dmz_ftp0_ip0 = "192.168.100.8"&lt;br /&gt;
&lt;br /&gt;
cn_srv_ip = "222.144.87.188"&lt;br /&gt;
&lt;br /&gt;
ca_pub_ip = "219.17.152.196"&lt;br /&gt;
&lt;br /&gt;
allow_sql_ip = "{" $cn_srv_ip $ca_pub_ip "}"&lt;br /&gt;
&lt;br /&gt;
##########################&lt;br /&gt;
##### TABLES - A structure used to hold lists of IP addresses.&lt;br /&gt;
##########################&lt;br /&gt;
table &amp;lt;blocked_ip&amp;gt; persist file "/etc/pf-blocked_ip"&lt;br /&gt;
&lt;br /&gt;
##########################&lt;br /&gt;
##### OPTIONS - Various options to control how PF works.&lt;br /&gt;
##########################&lt;br /&gt;
&lt;br /&gt;
### Sets the default behavior for filter rules that specify the block action.&lt;br /&gt;
### Return error codes for ports that are blocked. Allows faster error recovery.&lt;br /&gt;
#set block-policy return&lt;br /&gt;
&lt;br /&gt;
### Set pf's debugging level.&lt;br /&gt;
#set debug misc&lt;br /&gt;
&lt;br /&gt;
### Skip all PF processing on specified interface. This can be useful on loopback interfaces where filtering, normalization, queueing, etc, are not required.&lt;br /&gt;
set skip on lo0&lt;br /&gt;
&lt;br /&gt;
##########################&lt;br /&gt;
##### NORMALIZATION&lt;br /&gt;
##########################&lt;br /&gt;
### Traffic normalization for incoming packets - scrub provides a measure of protection against certain kinds of attacks based on incorrect handling of packet fragments.&lt;br /&gt;
### One reason not to scrub on an interface is if one is passing NFS through PF. Some non-OpenBSD platforms send (and expect) strange packets -- fragmented packets with the "do not fragment" bit set, which are (properly) rejected by scrub. This can be resolved by use of the no-df option. Another reason is some multi-player games have connection problems passing through PF with scrub enabled. Other than these somewhat unusual cases, scrubbing all packets is a highly recommended practice.&lt;br /&gt;
### The scrub directive syntax is very similar to the filtering syntax which makes it easy to selectively scrub certain packets and not others. The no keyword can be used in front of scrub to specify packets that will not be scrubbed. Just as with nat rules, the first matching rule wins.&lt;br /&gt;
scrub in all&lt;br /&gt;
&lt;br /&gt;
##########################&lt;br /&gt;
##### QUEUEING - Provides bandwidth control and packet prioritization.&lt;br /&gt;
##########################&lt;br /&gt;
&lt;br /&gt;
##########################&lt;br /&gt;
##### TRANSLATION&lt;br /&gt;
##########################&lt;br /&gt;
### NAT&lt;br /&gt;
nat on $wan_if from $dmz_if/24 to any -&amp;gt; $wan_if&lt;br /&gt;
&lt;br /&gt;
### [HTTP] RDR Outside to DMZ&lt;br /&gt;
rdr on $wan_if proto tcp from any to $wan_if port 80 -&amp;gt; $dmz_www_ip&lt;br /&gt;
&lt;br /&gt;
### [MYSQL] RDR Outside to DMZ&lt;br /&gt;
rdr on $wan_if proto tcp from $allow_sql_ip to $wan_if port 3306 -&amp;gt; $dmz_sql_ip&lt;br /&gt;
&lt;br /&gt;
### [RSYNCD] RDR Outside to DMZ&lt;br /&gt;
rdr on $wan_if proto tcp from $cn_srv_ip to $wan_if port 873 -&amp;gt; $dmz_www_ip&lt;br /&gt;
&lt;br /&gt;
### [MAIL] RDR Outside to DMZ&lt;br /&gt;
#rdr on $wan_if proto tcp from any to $wan_if/32 port {25 110} -&amp;gt; 192.168.10.2&lt;br /&gt;
&lt;br /&gt;
### [FTP] RDR Outside to DMZ&lt;br /&gt;
#rdr on $wan_if proto tcp from $allow_ftp_ip to $wan_if port 21 -&amp;gt; 192.168.10.8 port 21&lt;br /&gt;
&lt;br /&gt;
### [FTP] RDR DMZ to Outside (through ftp-proxy)&lt;br /&gt;
### Note: make sure you have this line "ftpproxy_enable="YES"" in your /etc/rc.conf.&lt;br /&gt;
nat-anchor "ftp-proxy/*"&lt;br /&gt;
rdr-anchor "ftp-proxy/*"&lt;br /&gt;
rdr pass proto tcp from any to $wan_if port 21 -&gt; 127.0.0.1 port 8021&lt;br /&gt;
&lt;br /&gt;
### [RAID-3WARE]&lt;br /&gt;
#rdr on $wan_if proto tcp from $wan_if/26 to $wan_if port 888 -&amp;gt; $dmz_sql_ip&lt;br /&gt;
&lt;br /&gt;
##########################&lt;br /&gt;
##### FILTERING RULES - Allows the selective filtering or blocking of packets as they pass through any of the interfaces.&lt;br /&gt;
##### Filter rules can be given parameters to specify network address translation (NAT) and packet redirection.&lt;br /&gt;
##########################&lt;br /&gt;
### setup a default deny policy - block everything (inbound and outbound on all interfaces).&lt;br /&gt;
### Note: if you want to see the log file to debug your filter rules, change following line to "block log all", otherwise use "block all" instead..&lt;br /&gt;
block log all&lt;br /&gt;
&lt;br /&gt;
block in quick on $wan_if from &amp;lt;blocked_ip&amp;gt; to any&lt;br /&gt;
&lt;br /&gt;
### activate spoofing protection for all interfaces.&lt;br /&gt;
block in quick from urpf-failed&lt;br /&gt;
&lt;br /&gt;
### [DNS] Outside to Router&lt;br /&gt;
pass in quick on $wan_if proto {tcp udp} from any to $wan_if port 53&lt;br /&gt;
&lt;br /&gt;
### [DNS] DMZ to Router&lt;br /&gt;
pass in quick on $dmz_if proto {tcp udp} from $dmz_if/24 to any port 53&lt;br /&gt;
&lt;br /&gt;
### [DNS] Router to Outside&lt;br /&gt;
pass out quick on $wan_if proto {tcp udp} from $wan_if to any port 53&lt;br /&gt;
&lt;br /&gt;
### [DNS] Router to DMZ&lt;br /&gt;
pass out quick on $dmz_if proto {tcp udp} from $dmz_if to $dmz_if/24 port 53&lt;br /&gt;
&lt;br /&gt;
### [HTTP] Outside to DMZ&lt;br /&gt;
pass in quick on $wan_if proto tcp from any to $dmz_www_ip port 80&lt;br /&gt;
pass out quick on $dmz_if proto tcp from any to $dmz_www_ip port 80&lt;br /&gt;
&lt;br /&gt;
### [HTTP] DMZ to Router&lt;br /&gt;
### Note: FreeBSD's portsnap command uses port 80 to grab latest FreeBSD ports/patches.&lt;br /&gt;
pass in quick on $dmz_if proto tcp from $dmz_if/24 to any port 80&lt;br /&gt;
&lt;br /&gt;
### [HTTP] Router to Outside&lt;br /&gt;
pass out quick on $wan_if proto tcp from $wan_if to any port 80&lt;br /&gt;
&lt;br /&gt;
### [MYSQL] DMZ to Outside&lt;br /&gt;
pass in quick on $dmz_if proto tcp from $dmz_sql_ip to $cn_srv_ip port 3306&lt;br /&gt;
pass out quick on $wan_if proto tcp from $wan_if to $cn_srv_ip port 3306&lt;br /&gt;
&lt;br /&gt;
### [MYSQL] Outside to DMZ&lt;br /&gt;
pass in quick on $wan_if proto tcp from $allow_sql_ip to $dmz_sql_ip port 3306&lt;br /&gt;
pass out quick on $dmz_if proto tcp from $allow_sql_ip to $dmz_sql_ip port 3306&lt;br /&gt;
&lt;br /&gt;
### [SMTP] DMZ to Outside&lt;br /&gt;
pass in quick on $dmz_if proto tcp from $dmz_www_ip to any port 25&lt;br /&gt;
pass out quick on $wan_if proto tcp from $wan_if to any port 25&lt;br /&gt;
&lt;br /&gt;
### [RSYNCD] Outside to DMZ&lt;br /&gt;
pass in quick on $wan_if proto tcp from $cn_srv_ip to $dmz_www_ip port 873&lt;br /&gt;
pass out quick on $dmz_if proto tcp from $cn_srv_ip to $dmz_www_ip port 873&lt;br /&gt;
&lt;br /&gt;
### [SSH] Outside to Router&lt;br /&gt;
pass in quick on $wan_if proto tcp from $allow_ssh_ip to $wan_if port 22 flags S/SA keep state&lt;br /&gt;
&lt;br /&gt;
### [SSH] Router to DMZ&lt;br /&gt;
pass out quick on $dmz_if proto tcp from $dmz_if to $dmz_if/24 port 22 flags S/SA keep state&lt;br /&gt;
&lt;br /&gt;
### [ICMP] DMZ/LAN to ANY&lt;br /&gt;
pass in quick on $dmz_if proto icmp from {$dmz_if/24 $lan_net} to any icmp-type $icmp_types&lt;br /&gt;
&lt;br /&gt;
### [ICMP] Router to Outside&lt;br /&gt;
pass out quick on $wan_if proto icmp from $wan_if to any icmp-type $icmp_types&lt;br /&gt;
&lt;br /&gt;
### [ICMP] DMZ to DMZ/LAN&lt;br /&gt;
pass out quick on $dmz_if proto icmp from $dmz_if/24 to {$dmz_if/24 $lan_net} icmp-type $icmp_types&lt;br /&gt;
&lt;br /&gt;
### [NTP] DMZ to Router&lt;br /&gt;
pass in quick on $dmz_if proto {tcp udp} from $dmz_if/24 to any port 123&lt;br /&gt;
&lt;br /&gt;
### [NTP] Router to Outside&lt;br /&gt;
pass out quick on $wan_if proto {tcp udp} from $wan_if to any port 123&lt;br /&gt;
&lt;br /&gt;
### [FTP] We need to have an anchor for ftp-proxy.&lt;br /&gt;
anchor "ftp-proxy/*"&lt;br /&gt;
&lt;br /&gt;
### [FTP] from DMZ to ANY&lt;br /&gt;
pass in quick log on $dmz_if proto {tcp} from $dmz_if/24 to any port 21&lt;br /&gt;
pass in quick log on $dmz_if proto {tcp} from $dmz_if/24 to any port &gt; 1023&lt;br /&gt;
&lt;br /&gt;
### [FTP] from ROUTER to ANY&lt;br /&gt;
pass out quick log on $wan_if proto {tcp} from $wan_if to any port 21&lt;br /&gt;
pass out quick log on $wan_if proto {tcp} from $wan_if to any port &gt; 1023&lt;br /&gt;
&lt;br /&gt;
### [FTP] from ANY to $dmz_ftp0_ip&lt;br /&gt;
pass out quick on $dmz_if proto {tcp} from $dmz_if to $dmz_ftp0_ip0 port 21&lt;br /&gt;
&lt;br /&gt;
### [NICNAME] DMZ to Router&lt;br /&gt;
pass in quick on $dmz_if proto tcp from $dmz_if/24 to any port 43&lt;br /&gt;
&lt;br /&gt;
### [NICNAME] Router to Outside&lt;br /&gt;
pass out quick on $wan_if proto tcp from $wan_if to any port 43&lt;br /&gt;
&lt;br /&gt;
### [SVN] Router to DMZ&lt;br /&gt;
pass out quick on $dmz_if proto tcp from $dmz_if to $dmz_svn_ip port 3690&lt;br /&gt;
&lt;br /&gt;
### [RAID-3WARE]&lt;br /&gt;
#pass in quick on $wan_if proto tcp from $wan_if/26 to $dmz_sql_ip port 888&lt;br /&gt;
#pass out quick on $dmz_if proto tcp from $wan_if/26 to $dmz_sql_ip port 888&lt;br /&gt;
&lt;br /&gt;
### [TRACEROUTE] Allow outgoing Trace route&lt;br /&gt;
#pass out on $ext_if inet proto udp from any to any port 33433 &amp;gt;&amp;lt; 33626 keep state &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Solution to No ALTQ support in kernel ALTQ related functions disabled&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Recompile your kernel:&lt;/b&gt;&lt;br /&gt;
# cd /usr/src/sys/`uname -m`/conf&lt;br /&gt;
# cp GENERIC MYKERNEL8.2&lt;br /&gt;
&lt;br /&gt;
# vim MYKERNEL8.2&lt;br /&gt;
&lt;pre&gt;### PF Packet Filter Related settings
device pf
device pflog
device pfsync

options         ALTQ
options         ALTQ_CBQ        # Class Bases Queuing (CBQ)
options         ALTQ_RED        # Random Early Detection (RED)
options         ALTQ_RIO        # RED In/Out
options         ALTQ_HFSC       # Hierarchical Packet Scheduler (HFSC)
options         ALTQ_PRIQ       # Priority Queuing (PRIQ)
options         ALTQ_NOPCC      # Required for SMP build&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; to view a list of available options:&lt;br /&gt;
# cat /usr/src/sys/conf/NOTES&lt;br /&gt;
# cat /usr/src/sys/`uname -m`/conf/DEFAULTS&lt;br /&gt;
&lt;br /&gt;
# cd /usr/src&lt;br /&gt;
# make buildkernel KERNCONF=MYKERNEL8.2&lt;br /&gt;
# make installkernel KERNCONF=MYKERNEL8.2&lt;br /&gt;
&lt;br /&gt;
# sync ; reboot&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; if the system could not boot properly, press any keys other than enter key when you see the count down number. and type following at boot: prompt:&lt;br /&gt;
boot: unload&lt;br /&gt;
boot: /kernel.old&lt;br /&gt;
&lt;a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/boot-blocks.html"&gt;http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/boot-blocks.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Useful Commands&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Make sure the pf kernel module has been loaded:&lt;/strong&gt;&lt;br /&gt;
# kldstat | grep pf&lt;br /&gt;
2    2 0xc0f8c000 32e98    pf.ko&lt;br /&gt;
3    1 0xc61db000 3000     pflog.ko&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Diable the packet filter&lt;/strong&gt;&lt;br /&gt;
# pfctl -d&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Enable the packet filter&lt;/strong&gt;&lt;br /&gt;
# pfctl -e&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Flush all (nat, filter, queue, state, info, table) rules and reload from the file /etc/pf.conf&lt;/strong&gt;&lt;br /&gt;
# pfctl -F all -f /etc/pf.conf&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;If you are setting up pf remotely, and you are not confident enough with your PF rules, you might be blocked out by the wrong rules. Following command allows you to try the rules, and disable PF after 20 seconds:&lt;/strong&gt;&lt;br /&gt;
# pfctl -f /etc/pf.conf; sleep 20; pfctl -d&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;This does not actually load any rules, but allows you to check for syntax errors in the file before you do load the ruleset. This is obviously good for testing.&lt;/strong&gt;&lt;br /&gt;
# pfctl -vnf /etc/pf.conf&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Report on the currently loaded filter ruleset.&lt;/strong&gt;&lt;br /&gt;
# pfctl -s rules&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Report on the currently loaded nat ruleset.&lt;/strong&gt;&lt;br /&gt;
# pfctl -s nat&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Report on the currently running state table (very useful).&lt;/strong&gt;&lt;br /&gt;
# pfctl -s state&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Tables can be manipulated on the fly by using pfctl(8). For instance, to add entries to the &amp;lt;blocked_ip&amp;gt; table:&lt;/strong&gt;&lt;br /&gt;
# pfctl -t blocked_ip -T add 218.70.0.0/16&lt;br /&gt;
&lt;br /&gt;
This will also create the &amp;lt;blocked_ip&amp;gt; table if it doesn't already exist.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;To list the addresses in a table: &lt;/strong&gt;&lt;br /&gt;
# pfctl -t blocked_ip -T show&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Note:&lt;/strong&gt; The -v argument can also be used with -T show to display statistics for each table entry.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;To remove addresses from a table: &lt;/strong&gt;&lt;br /&gt;
# pfctl -t blocked_ip -T delete 218.70.0.0/16 &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Troubleshooting&lt;/span&gt;&lt;br /&gt;
&lt;strong&gt;dump traffic on a network, see packets that match a certain port&lt;/strong&gt;&lt;br /&gt;
# tcpdump -ni re0 port 53&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;You may also want to limit tcpdump to just show icmp:&lt;/strong&gt;&lt;br /&gt;
# tcpdump -ni re0 icmp&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Or just to/from a certain host:&lt;/strong&gt;&lt;br /&gt;
# tcpdump -ni re0 icmp and host 172.16.70.12&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reading a PF (packet filter) log file&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The log file written by pflogd is in binary format and cannot be read using a text editor. Tcpdump must be used to view the log.&lt;br /&gt;
&lt;br /&gt;
To view the log file:&lt;br /&gt;
&lt;br /&gt;
# tcpdump -n -e -ttt -r /var/log/pf.log&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Note:&lt;/strong&gt; that using tcpdump(8) to watch the pflog file does not give a real time display. A real time display of logged packets is achieved by using the pflog0 interface: &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue;"&gt;# ifconfig | grep pflog&lt;/span&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;# tcpdump -n -e -ttt -i pflog0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Filtering Log Output&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Because pflogd logs in tcpdump binary format, the full range of tcpdump features can be used when reviewing the logs. For example, to only see packets that match a certain port: &lt;br /&gt;
&lt;br /&gt;
# tcpdump -n -e -ttt -r /var/log/pf.log port 80&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-large;"&gt;Reference:&lt;/span&gt;&lt;br /&gt;
set up PF (packet filter) firewall on FreeBSD 8.2&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/12/set-up-pf-packet-filter-on-freebsd.html"&gt;http://gala4th.blogspot.com/2010/12/set-up-pf-packet-filter-on-freebsd.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
PF supports FTP servers and FTP clients behind NAT&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2012/01/pf-supports-ftp-servers-and-ftp-clients.html"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.openbsd.org/faq/pf/index.html"&gt;http://www.openbsd.org/faq/pf/index.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.openbsd.org/faq/pf/nat.html"&gt;http://www.openbsd.org/faq/pf/nat.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.weithenn.org/cgi-bin/wiki.pl?PF-%E5%88%A9%E7%94%A8_PF_%E8%BC%95%E9%AC%86%E9%81%94%E6%88%90_NAT"&gt;http://www.weithenn.org/cgi-bin/wiki.pl?PF-%E5%88%A9%E7%94%A8_PF_%E8%BC%95%E9%AC%86%E9%81%94%E6%88%90_NAT&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.thedeepsky.com/howto/newbie_pf_guide.php"&gt;http://www.thedeepsky.com/howto/newbie_pf_guide.php&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://home.nuug.no/~peter/pf/en/ftpproblem.html"&gt;http://home.nuug.no/~peter/pf/en/ftpproblem.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://slacksite.com/other/ftp.html"&gt;Active FTP vs. Passive FTP, a Definitive Explanation&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2012/01/active-ftp-vs-passive-ftp-definitive.html"&gt;Active FTP vs. Passive FTP, a Definitive Explanation&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-9217762294454936062?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/Zez_X9XryMw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/9217762294454936062/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=9217762294454936062" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/9217762294454936062?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/9217762294454936062?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/Zez_X9XryMw/set-up-pf-packet-filter-on-freebsd.html" title="set up PF (packet filter) firewall on FreeBSD 8.2" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2010/12/set-up-pf-packet-filter-on-freebsd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08CRH4yeyp7ImA9WhRUEEU.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-6169305542237635522</id><published>2012-01-20T12:04:00.000-08:00</published><updated>2012-01-20T12:04:25.093-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-20T12:04:25.093-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><category scheme="http://www.blogger.com/atom/ns#" term="Revision Control" /><title>Setting up a Secure Subversion Server</title><content type="html">Setting up a Secure Subversion Server&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Backing up your scripts.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
# tar czvf - /usr/local/etc/www/data | ssh dru@192.168.2.2 "cat &amp;gt; www.tar.gz"&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Preparing the System&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In my scenario, it was important that only the members of the development team have access to the repository. We also chose to have the repository on a system separate from the actual web server and left it up to the web administrator to copy over files from the repository to the web server as he saw fit.&lt;br /&gt;
&lt;br /&gt;
To accomplish this, start by creating a backup of the existing directory structure you wish to put under revision control, and send it securely to the repository server. In my case, I backed up the www data on the web server to an internal server at 192.168.2.2.&lt;br /&gt;
&lt;br /&gt;
Add a user called svn.&lt;br /&gt;
&lt;br /&gt;
# adduser&lt;br /&gt;
&lt;br /&gt;
Next, on the repository system, create a new group called svn and add to it any existing user accounts that need access to the repository. For example, I added my existing web administrator as I created the group by adding this line to /etc/group:&lt;br /&gt;
&lt;br /&gt;
# vi /etc/group&lt;br /&gt;
svn:*:3690:webadmin&lt;br /&gt;
&lt;br /&gt;
Then, create a new user called svn and, if necessary, any missing user accounts that need access to the repository. Make sure each account is a member of the svn group and has a password and a valid shell. I used sysinstall to create user accounts for the new web developers. When I finished, I double-checked the membership of the svn group. It looked something like this:&lt;br /&gt;
&lt;br /&gt;
# grep svn /etc/group&lt;br /&gt;
svn:*:3690:webadmin,devel1,devel2&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Dealing with umask&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Before installing Subversion, take a close look at the existing umask for the svn user. On my FreeBSD system it was:&lt;br /&gt;
&lt;br /&gt;
# su - svn&lt;br /&gt;
% umask&lt;br /&gt;
022&lt;br /&gt;
&lt;br /&gt;
In Unix, the umask value determines the default permissions of a newly created directory or file. It does this by defining which permissions to disable. If you remember:&lt;br /&gt;
&lt;br /&gt;
r = 4&lt;br /&gt;
w = 2&lt;br /&gt;
x = 1&lt;br /&gt;
&lt;br /&gt;
you'll see that this umask doesn't turn off any (0) permissions for the user (svn); it turns off write (2) for the group (svn); and it turns off write (2) for world.&lt;br /&gt;
&lt;br /&gt;
Because the members of the svn group should be able to write to the repository, change that group 2 to a 0. If you don't want nongroup members even to be aware of the existence of the repository, also change the world 2 to a 7.&lt;br /&gt;
&lt;br /&gt;
The easy part is changing the umask for the svn user's shell. If it uses csh:&lt;br /&gt;
&lt;br /&gt;
# su - svn&lt;br /&gt;
svn # vi ~svn/.cshrc&lt;br /&gt;
# A righteous umask&lt;br /&gt;
umask 027&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note&lt;/b&gt;: the meaning of each umask:&lt;br /&gt;
umask 002 // File permission 644. Owner can read/write. Group and Others can only read.&lt;br /&gt;
umask 007 // File permission 660. Owner and Group can read/write. Others can not read or write.&lt;br /&gt;
umask 027 // File permission 640. Owner can read/write. Group can read. Others can not read or write.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="color: blue;"&gt;Note: I personally prefer to set umask 027. There is a security reason behind the thought. In order to prevent bad scripts trying to create new scripts or modify existing scripts on your server, you can have "svn update" running automatically in crontab. That will take care of source code update part. Then, you would want to make "svn" user to be the only user that has the write permission. www group users will only have read permission.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
then find the existing umask line and change it to either 002, 007 or 027.&lt;br /&gt;
&lt;br /&gt;
If your svn user has a shell other than csh, make your edit in your chosen shell's configuration file.&lt;br /&gt;
&lt;br /&gt;
Once you've saved your changes to ~svn/.cshrc (or wherever), don't forget to tell the shell:&lt;br /&gt;
&lt;br /&gt;
svn # source ~svn/.cshrc&lt;br /&gt;
&lt;br /&gt;
Repeat the umask command to verify that your changes have taken place.&lt;br /&gt;
Installing Subversion with the correct umask&lt;br /&gt;
&lt;br /&gt;
If you chose a umask of 002, you can compile a wrapper into Subversion when you build it from the ports collection. If you chose a umask of 007 or 027, or prefer to install the precompiled version of Subversion, create a wrapper script to ensure that the Subversion binaries use your umask value.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;To compile in a wrapper that sets a umask of 007 or 027:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/devel/subversion&lt;br /&gt;
# make config-recursive&lt;br /&gt;
# make install clean&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;To compile in a wrapper that sets a umask of 002:&lt;/span&gt;&lt;br /&gt;
# cd /usr/ports/devel/subversion&lt;br /&gt;
# make -DWITH_SVNSERVE_WRAPPER install clean&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Note:&lt;/span&gt; you do NOT need -DWITH_SVNSERVE_WRAPPER option if you decided to use umask of 007 or 027.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make sure you DO uncheck this option:&lt;/b&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;[] BDB=off "db4 repository backend"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Because some poeple said:&lt;br /&gt;
&lt;br /&gt;
- I never used a BDB repos myself, exactly because the Subversion manual warns strongly against it. So second this. – jfs Sep 23 at 8:30&lt;br /&gt;
&lt;br /&gt;
- I also second this - we used to have Subversion BDB repository problems. Switching to the FSFS repository type helped. – Phill Sacre Sep 23 at 8:38&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Alternatively, to install the precompiled binary:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
# pkg_add -r subversion&lt;br /&gt;
&lt;br /&gt;
Note: before installing by either method, finish reading the article. You may find some additional compile options that interest you.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;If you didn't compile in your wrapper (that means you use a umask of 007 or 027), move your existing binary and create your own wrapper script:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
# mv /usr/local/bin/svn /usr/local/bin/svn.orig&lt;br /&gt;
&lt;br /&gt;
# vi /usr/local/bin/svn&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: blue;"&gt;#!/bin/sh

### initialize
svnarg=""

### use encoding utf-8 as default if run "svn ci" or "svn commit".
if [ "$1" != "help" ]; then
  for myarg in "$@"; do
    if [ "${myarg}" = "commit" ] || [ "${myarg}" = "ci" ]; then
      svnarg="--encoding utf-8"
      break
    fi
  done
fi

### wrapper script to set umask to 027 on subversion binaries
### Note: the meaning of each umask:
### umask 002 // File permission 644. Owner can read/write. Group and Others can only read.
### umask 007 // File permission 660. Owner and Group can read/write. Others can not read or write.
### umask 027 // File permission 640. Owner can read/write. Group can read. Others can not read or write.
umask 027

### svn command
/usr/local/bin/svn.orig ${svnarg} "$@"&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
Set your umask to either 002, 007 or 027 so that it is the same as the umask for your svn user.&lt;br /&gt;
&lt;br /&gt;
Don't forget to make your wrapper script executable:&lt;br /&gt;
&lt;br /&gt;
# chmod +x /usr/local/bin/svn&lt;br /&gt;
&lt;br /&gt;
Repeat the same steps for proj2 files.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Creating the Repository&lt;/span&gt;&lt;br /&gt;
Create a central place to store all repositories.&lt;br /&gt;
# mkdir /usr/local/repositories&lt;br /&gt;
&lt;br /&gt;
# chown svn:svn /usr/local/repositories&lt;br /&gt;
&lt;br /&gt;
Now that your environment is set up properly, you're ready to create the repository itself.&lt;br /&gt;
&lt;br /&gt;
Log in as the user svn to ensure that both the svn user and the svn group own the files you create in the repository.&lt;br /&gt;
# su - svn&lt;br /&gt;
&lt;br /&gt;
svn # cd /usr/local/repositories&lt;br /&gt;
svn # svnadmin create proj1&lt;br /&gt;
svn # svnadmin create proj2&lt;br /&gt;
&lt;br /&gt;
In this example, I've called my repository "proj1" and "proj2" two separate repositories. You can choose any name that is useful to you.&lt;br /&gt;
&lt;br /&gt;
svnadmin create simply creates the directory infrastructure required by the Subversion tools:&lt;br /&gt;
&lt;br /&gt;
svn # ls -F proj1 proj2&lt;br /&gt;
proj1:&lt;br /&gt;
README.txt conf/ db/ format hooks/ locks/&lt;br /&gt;
&lt;br /&gt;
proj2:&lt;br /&gt;
README.txt conf/ db/ format hooks/ locks/ db/ hooks/&lt;br /&gt;
&lt;br /&gt;
Notice that db directory? By default, Subversion uses databases to track changes to the files that you place under revision control. This means that you must import your data into those databases.&lt;br /&gt;
&lt;br /&gt;
Edit svnserve.conf &amp;amp; passwd file:&lt;br /&gt;
svn # vi /usr/local/repositories/proj1/conf/svnserve.conf&lt;br /&gt;
[general]&lt;br /&gt;
anon-access = none&lt;br /&gt;
auth-access = write&lt;br /&gt;
password-db = passwd&lt;br /&gt;
&lt;br /&gt;
svn # vi /usr/local/repositories/proj1/conf/passwd&lt;br /&gt;
[users]&lt;br /&gt;
danny = mypassword&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Start SVN server as a stand-alone daemon&lt;/span&gt;&lt;br /&gt;
# /usr/local/bin/svnserve -d --listen-port=3690 --listen-host=0.0.0.0 -r /usr/local/repositories&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Preparing Files to be imported&lt;/span&gt;&lt;br /&gt;
At that point, I untarred my backup so that I had some data to import. If you do this, don't restore directly into the /usr/local/repositories/proj1 directory. (It's a database, remember?) Instead, I first made a new directory structure:&lt;br /&gt;
# mkdir /usr/local/www/apache22/data/proj1&lt;br /&gt;
# cd /usr/local/www/apache22/data/proj1&lt;br /&gt;
# mkdir branches tags trunk&lt;br /&gt;
# cd trunk&lt;br /&gt;
# tar xzvf /full/path/to/www.tar.gz .&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Importing the Data&lt;/span&gt;&lt;br /&gt;
Next, it's time to import the information from /usr/local/www/apache22/data/proj1 into the Subversion databases. To do so, use the svn import command:&lt;br /&gt;
# su - svn&lt;br /&gt;
svn # cd /usr/local/www/apache22/data&lt;br /&gt;
svn # svn import proj1 file:///usr/local/repositories/proj1 -m "initial import"&lt;br /&gt;
svn # svn import proj2 file:///usr/local/repositories/proj2 -m "initial import"&lt;br /&gt;
&lt;br /&gt;
svn import is one of many svn commands available to users. Type svn help to see the names of all the available commands. If you insert one of those commands between svn and help, as in svn import help, you'll receive help on the syntax for that specified command.&lt;br /&gt;
&lt;br /&gt;
After svn import, specify the name of the directory containing the data to import (proj1 or proj2). Your data doesn't have to be in the same directory; simply specify the full path to the data, but ensure that your svn user has permission to access the data you wish to import. Note: once you've successfully imported your data, you don't have to keep an original copy on disk. In my case, I issued the command rm -Rf www.&lt;br /&gt;
&lt;br /&gt;
Next, notice the syntax I used when specifying the full path to the repository. Subversion supports multiple URL schemas or "repository access" RA modules. Verify which schemas your svn supports with:&lt;br /&gt;
&lt;br /&gt;
# svn --version&lt;br /&gt;
svn, version 1.1.3 (r12730)&lt;br /&gt;
compiled Mar 20 2005, 11:04:16&lt;br /&gt;
&lt;br /&gt;
Copyright (C) 2000-2004 CollabNet.&lt;br /&gt;
Subversion is open source software, see http://subversion.tigris.org/&lt;br /&gt;
This product includes software developed by CollabNet (http://www.Collab.Net/).&lt;br /&gt;
&lt;br /&gt;
The following repository access (RA) modules are available:&lt;br /&gt;
&lt;br /&gt;
* ra_dav : Module for accessing a repository via WebDAV (DeltaV) protocol.&lt;br /&gt;
- handles 'http' schema&lt;br /&gt;
- handles 'https' schema&lt;br /&gt;
* ra_local : Module for accessing a repository on local disk.&lt;br /&gt;
- handles 'file' schema&lt;br /&gt;
* ra_svn : Module for accessing a repository using the svn network protocol.&lt;br /&gt;
- handles svn schema&lt;br /&gt;
&lt;br /&gt;
Because I wished to access the repository on the local disk, I used the file:/// schema. I also appended www at the very end of the URL, as I wish that particular part of the repository to be available by that name. Yes, you can import multiple directory structures into the same Subversion repository, so give each one a name that is easy for you and your users to remember.&lt;br /&gt;
&lt;br /&gt;
Finally, I used the -m message switch to append the comment "initial import" to the repository log. If I hadn't included this switch, svn would have opened the log for me in the user's default editor (vi) and asked me to add a comment before continuing.&lt;br /&gt;
&lt;br /&gt;
This is a very important point. The whole reason to install a revision control system is to allow multiple users to modify files, possibly even simultaneously. It's up to each user to log clearly which changes they made to which files. It's your job to make your users aware of the importance of adding useful comments whenever an svn command prompts them to do so.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Edit /etc/rc.conf:&lt;/span&gt;&lt;br /&gt;
Just went through this (thank you) however I came across the issue where my FreeBSD box was just listening on tcp6. I'm using this internally on my network but without a tcp6 router this of course doesn't help. To make it work, I just modified my rc.conf to listen on host 0.0.0.0 (telling it to use tcp4). Also for anyone who wants it to start easily on boot, add this to your /etc/rc.conf (replacing the data dir, user, and group as necessary)&lt;br /&gt;
&lt;br /&gt;
svnserve_enable="YES"&lt;br /&gt;
svnserve_flags="-d --listen-port=3690 --listen-host=0.0.0.0"&lt;br /&gt;
svnserve_data="/usr/local/repositories"&lt;br /&gt;
svnserve_user="svn"&lt;br /&gt;
svnserve_group="svn"&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Edit Firewall Rules:&lt;/span&gt;&lt;br /&gt;
# vi /usr/local/etc/ipfw.rules&lt;br /&gt;
### SVN&lt;br /&gt;
$IPF 250 allow tcp from 192.168.500.0/24 to any 3690 in&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Refresh Firewall Rules:&lt;/span&gt;&lt;br /&gt;
# sh /usr/local/etc/ipfw.rules&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Backup Repositories&lt;/span&gt;&lt;br /&gt;
There are at least four ways to backup repositories:&lt;br /&gt;
- SVN hotcopy&lt;br /&gt;
- SVN dump&lt;br /&gt;
- tar entire directory.&lt;br /&gt;
- svnsync (also use svnsync + hook script is great. Sync at each commit)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;SVN Hotcopy backup&lt;/span&gt;&lt;br /&gt;
# svnadmin hotcopy /usr/local/repositories/proj1 /home/bot/repositories/proj1&lt;br /&gt;
Note: the target (destination) directory must be a empty directory.&lt;br /&gt;
More: &lt;a href="http://gala4th.blogspot.com/2009/08/svn.html"&gt;http://gala4th.blogspot.com/2009/08/svn.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;SVN Restore from hotcopy&lt;/span&gt;&lt;br /&gt;
Hotcopy should produce a usable file-level repository. You should be&lt;br /&gt;
able to use it as-is if the ownership and permissions are suitable. If&lt;br /&gt;
you are running a server, you may have to copy back to the location the&lt;br /&gt;
server expects or adjust the configuration to use the new location.&lt;br /&gt;
&lt;br /&gt;
You must read carefully the following sections:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.reposadmin.maint.migrate"&gt;http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.reposadmin.maint.migrate&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.reposadmin.maint.backup"&gt;http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.reposadmin.maint.backup&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.ref.svnadmin.c.dump"&gt;http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.ref.svnadmin.c.dump&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.ref.svnadmin.c.load"&gt;http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.ref.svnadmin.c.load&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.ref.svnadmin.c.hotcopy"&gt;http://svnbook.red-bean.com/nightly/en/svn-book.html#svn.ref.svnadmin.c.hotcopy&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
And you will be golden and all set.&lt;br /&gt;
&lt;br /&gt;
As you read those links, then you must realize by now that restoring a&lt;br /&gt;
hotcopy which is basically a copy of all your repository its easy just&lt;br /&gt;
copy to your Subversion scope, you may need to change owner&lt;br /&gt;
permissions and change your hook-scripts (only if you were using&lt;br /&gt;
hook-scripts) after this you will be ready to go.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;SVN Client - TortoiseSVN&lt;/span&gt;&lt;br /&gt;
On Windows, create folders:&lt;br /&gt;
C:\svn_repositories\proj1&lt;br /&gt;
C:\svn_repositories\proj2&lt;br /&gt;
&lt;br /&gt;
Right click on each folder (proj1 &amp;amp; proj2) &amp;gt; check out &amp;gt; enter respectively:&lt;br /&gt;
svn://192.168.100.156/proj1&lt;br /&gt;
svn://192.168.100.156/proj2&lt;br /&gt;
&lt;br /&gt;
or try command line:&lt;br /&gt;
# svn checkout svn://192.168.100.156/proj1 /usr/local/www/apache22/data/proj1&lt;br /&gt;
# svn update /usr/local/www/apache22/data/proj1&lt;br /&gt;
# svn update&lt;br /&gt;
# svn status /usr/local/www/apache22/data/proj1&lt;br /&gt;
# svn status -u&lt;br /&gt;
# svn add /usr/local/www/apache22/data/proj1/test111.php&lt;br /&gt;
# svn commit -m "LogMessage"&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Deciding Upon a URL Schema&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Congratulations! You now have a working repository. Now's the best time to take a closer look at the various URL schemas and choose the access method that best suits your needs.&lt;br /&gt;
&lt;br /&gt;
Chapter 6 of the freely available e-book Version Control with Subversion gives details about the possible configurations. You can choose to install the book when you compile the FreeBSD port by adding -DWITH_BOOK to your make command.&lt;br /&gt;
&lt;br /&gt;
If all of your users log in to the system either locally or through ssh, use the file:/// schema. Because users are "local" to the repository, this scenario doesn't open a TCP/IP port to listen for Subversion connections. However, it does require an active shell account for each user and assumes that your users are comfortable logging in to a Unix server. As with any shell account, your security depends upon your users choosing good passwords and you setting up repository permissions and group memberships correctly. Having users ssh to the system does ensure that they have encrypted sessions.&lt;br /&gt;
&lt;br /&gt;
Another possibility is to integrate Subversion into an existing Apache server. By default, the FreeBSD port of Subversion compiles in SSL support, meaning your users can have the ability to access your repository securely from their browsers using the https:// schema. However, if you're running Apache 2.x instead of Apache 1.x, remember to pass the -DWITH_MOD_DAV_SVN option to make when you compile your FreeBSD port.&lt;br /&gt;
&lt;br /&gt;
If you're considering giving browser access to your users, read carefully through the Apache httpd configuration section of the Subversion book first. You'll have to go through a fair bit of configuration; fortunately, the documentation is complete.&lt;br /&gt;
&lt;br /&gt;
A third approach is to use svnserve to listen for network connections. The book suggests running this process either through inetd or as a stand-alone daemon. Both of these approaches allow either anonymous access or access once the system has authorized a user using CRAM-MD5. Clients connect to svnserve using the svn:// schema.&lt;br /&gt;
&lt;br /&gt;
Anonymous access wasn't appropriate in my scenario, so I followed the configuration options for CRAM-MD5. However, I quickly discovered that CRAM-MD5 wasn't on my FreeBSD system. When a Google search failed to find a technique for integrating CRAM-MD5 with my Subversion binary, I decided to try the last option.&lt;br /&gt;
&lt;br /&gt;
This was to invoke svnserve in tunnel mode, which allows user authentication through the normal SSH mechanism as well as any restrictions you have placed in your /etc/ssh/sshd_config file. For example, I could use the AllowUsers keyword to control which users can authenticate to the system. Note that this schema uses svn+ssh://.&lt;br /&gt;
&lt;br /&gt;
The appeal of this method is that I could use an existing authentication scheme without forcing the user to actually be "on" the repository system. However, this network connection is unencrypted; the use of SSH is only to authenticate. If your data is sensitive, either have your users use file:// after sshing in or use https:// after you've properly configured Apache.&lt;br /&gt;
&lt;br /&gt;
If you decide to use the svnserve server and you compiled in the wrapper, it created a binary called svnserve.bin. Users won't be able to access the repository until:&lt;br /&gt;
&lt;br /&gt;
# cp /usr/local/bin/svnserve.bin /usr/local/bin/svnserve&lt;br /&gt;
&lt;br /&gt;
That's it for this installment. In the next column, I'll show how to start accessing the repository as a client.&lt;br /&gt;
&lt;br /&gt;
Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2010/01/setting-up-secure-subversion-server.html"&gt;http://gala4th.blogspot.com/2010/01/setting-up-secure-subversion-server.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://onlamp.com/pub/a/bsd/2005/05/12/FreeBSD_Basics.html"&gt;http://onlamp.com/pub/a/bsd/2005/05/12/FreeBSD_Basics.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blog.jostudio.net/2007/06/svn.html"&gt;http://blog.jostudio.net/2007/06/svn.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-6169305542237635522?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/sJcuz7r1GVs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/6169305542237635522/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=6169305542237635522" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/6169305542237635522?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/6169305542237635522?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/sJcuz7r1GVs/setting-up-secure-subversion-server.html" title="Setting up a Secure Subversion Server" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2010/01/setting-up-secure-subversion-server.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UBQHo6eyp7ImA9WhRUEEU.&quot;"><id>tag:blogger.com,1999:blog-2361800974999510068.post-8817873656609320635</id><published>2012-01-20T11:54:00.000-08:00</published><updated>2012-01-20T11:54:11.413-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-20T11:54:11.413-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FreeBSD" /><title>Install Jails on FreeBSD 8.2</title><content type="html">Install Jails on FreeBSD 8.2&lt;br /&gt;
&lt;br /&gt;
Jails, sometimes referred to as an enhanced replacement of chroot environments, are a very powerful tool for system administrators, but their basic usage can also be useful for advanced users.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Setting up the Host Environment&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
First, you will want to set up your real system's environment to be "jail-friendly".  &lt;br /&gt;
&lt;br /&gt;
For consistency, we will refer to the parent box as the "host environment", and to the jailed virtual machine as the "jail environment". Since jail is implemented using IP aliases, one of the first things to do is to disable IP services on the host system that listen on all local IP addresses for a service.  If a network service is present in the host environment that binds all available IP addresses rather than specific IP addresses, it may service requests sent to jail IP addresses if the jail did not bind the port. This means changing inetd(8) to only listen on the appropriate IP address, and so forth. Add the following to /etc/rc.conf in the host environment:&lt;br /&gt;
&lt;br /&gt;
sendmail_enable="NO"&lt;br /&gt;
inetd_flags="-wW -a 192.168.0.1"&lt;br /&gt;
rpcbind_enable="NO"&lt;br /&gt;
&lt;br /&gt;
man inetd for more information.&lt;br /&gt;
&lt;br /&gt;
192.168.0.1 is the native IP address for the host system, in this example. Daemons that run out of inetd(8) can be easily set to use only the specified host IP address.  Other daemons will need to be manually configured for some this is possible through the rc.conf(5) flags entries; for others it is necessary to modify per-application configuration files, or to recompile the applications. The following frequently deployed services must have their individual configuration files modified to limit the application to listening to a specific IP address:&lt;br /&gt;
&lt;br /&gt;
To configure sshd(8), it is necessary to modify /etc/ssh/sshd_config.&lt;br /&gt;
&lt;br /&gt;
To configure sendmail(8), it is necessary to modify&lt;br /&gt;
&lt;br /&gt;
/etc/mail/sendmail.cf.&lt;br /&gt;
&lt;br /&gt;
For named(8), it is necessary to modify /etc/namedb/named.conf.&lt;br /&gt;
&lt;br /&gt;
In addition, a number of services must be recompiled in order to run them in the host environment. This includes most applications providing services using rpc(3), such as rpcbind(8), nfsd(8), and mountd(8). In general, applications for which it is not possible to specify which IP address to bind should not be run in the host environment unless they should also service requests sent to jail IP addresses. Attempting to serve NFS from the host environment may also cause confusion, and cannot be easily reconfigured to use only specific IPs, as some NFS services are hosted directly from the kernel. Any third-party network software running in the host environment should also be checked and configured so that it does not bind all IP addresses, which would result in those services' also appearing to be offered by the jail environments.&lt;br /&gt;
&lt;br /&gt;
Once these daemons have been disabled or fixed in the host environment, it is best to reboot so that all daemons are in a known state, to reduce the potential for confusion later (such as finding that when you send mail to a jail, and its sendmail is down, the mail is delivered to the host, etc.).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Getting services to not listen to *&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
First off, we should make sure we get the system so that we have nothing listening on *, to check what what we need to modify issue this command&lt;br /&gt;
&lt;br /&gt;
# sockstat | grep "\*:[0-9]"&lt;br /&gt;
&lt;br /&gt;
This should give you a synopsys of all the processes and ports you need to trim down. Here are some hints with your ipv4 addr being 10.0.0.1 and your ipv6 addr being 2002::7ea9&lt;br /&gt;
&lt;br /&gt;
# vi /etc/rc.conf&lt;br /&gt;
sendmail_enable="NO"&lt;br /&gt;
inetd_flags="-wW -a 192.168.0.1"&lt;br /&gt;
rpcbind_enable="NO"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;sshd:&lt;/b&gt;&lt;br /&gt;
# vim /etc/ssh/sshd_config&lt;br /&gt;
&lt;br /&gt;
change ListenAddress derivative&lt;br /&gt;
&lt;br /&gt;
ListenAddress 192.168.0.1&lt;br /&gt;
ListenAddress 192.168.0.111&lt;br /&gt;
ListenAddress 2002::7ea9&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;syslogd:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.conf&lt;br /&gt;
### enable syslogd, no network socket will be opened for syslogd&lt;br /&gt;
syslogd_enable="YES"&lt;br /&gt;
syslogd_flags="-s -s"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;rsyncd:&lt;/b&gt;&lt;br /&gt;
# vim /usr/local/etc/rsyncd.conf&lt;br /&gt;
address = 192.168.0.1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;MySQL:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# vim /etc/my.cnf&lt;br /&gt;
bind-address=10.0.0.1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Samba:&lt;/b&gt; (this will get you most of the way there)&lt;br /&gt;
edit /usr/local/etc/smb.conf&lt;br /&gt;
change the following:&lt;br /&gt;
interfaces = 10.0.0.242/24 127.0.0.1&lt;br /&gt;
socket address = 10.0.0.242&lt;br /&gt;
&lt;br /&gt;
bind interfaces only = yes&lt;br /&gt;
note: if you don't need wins lookups and netbios name translation&lt;br /&gt;
you can safely disable nmbd. There doesn't seem to be a way&lt;br /&gt;
for nmb to not listen to *:138 anyhow.&lt;br /&gt;
&lt;br /&gt;
To disable nmb go to /etc/rc.conf and replace samba_enable="YES" with smbd_enable="YES"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;open ntpd&lt;/b&gt; (xntpd listens on all and cannot be changed)&lt;br /&gt;
&lt;br /&gt;
# vim /usr/local/etc/ntpd.conf&lt;br /&gt;
listen on 10.0.0.1&lt;br /&gt;
listen on 2002::7ea9&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;bind&lt;/b&gt;&lt;br /&gt;
edit your named.conf (may be in /var/named/etc/named.conf)&lt;br /&gt;
In the options section:&lt;br /&gt;
listen-on { 10.0.0.242; };&lt;br /&gt;
listen-on-v6 port 53 { 2002:d8fe:10f1:6:202:b3ff:fea9:7ea9; };&lt;br /&gt;
query-source address 10.0.0.242 port *;&lt;br /&gt;
query-source-v6 address 2002:d8fe:10f1:6:202:b3ff:fea9:7ea9 port *;&lt;br /&gt;
&lt;br /&gt;
The file system layout is described in the following list:&lt;br /&gt;
&lt;br /&gt;
- Each jail will be mounted under the /home/jail/THE_JAIL_NAME directory.&lt;br /&gt;
&lt;br /&gt;
- /home/jail/read-only/root # is the template for each jail and the read-only partition for all of the jails.&lt;br /&gt;
&lt;br /&gt;
- A blank directory will be created for each jail under the /home/jail directory.&lt;br /&gt;
&lt;br /&gt;
- Each jail shall have its own read-write system that is based upon /home/jail/read-only/skel.&lt;br /&gt;
&lt;br /&gt;
- Each jailspace (read-write portion of each jail) shall be created in /home/jail/read-write/THE_JAIL_NAME.&lt;br /&gt;
&lt;br /&gt;
- Each jail will have a /s directory, that will be linked to the read-write portion of the system.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating the Template&lt;/b&gt;&lt;br /&gt;
This section will describe the steps needed to create the master template that will be the read-only portion for the jails to use.&lt;br /&gt;
&lt;br /&gt;
It is always a good idea to update the FreeBSD system to the latest -RELEASE branch. Check the corresponding Handbook Chapter to accomplish this task. In the case the update is not feasible, the buildworld will be required in order to be able to proceed. Additionally, the sysutils/cpdup package will be required. We will use the portsnap(8) utility to download the FreeBSD Ports Collection. The Handbook Portsnap Chapter is always good reading for newcomers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install cpdup&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/sysutils/cpdup ; make install clean&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create directories&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# mkdir /home/jail&lt;br /&gt;
# mkdir /home/jail/read-only&lt;br /&gt;
# mkdir /home/jail/read-write&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create a directory structure for the read-only file system which will contain the FreeBSD binaries for our jails:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# mkdir /home/jail/read-only/root&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Change directory to the FreeBSD source tree and install the read-only file system to the jail template:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /usr/src&lt;br /&gt;
&lt;br /&gt;
If you have already rebuilt your userland using make world or make buildworld, you can skip following step and install your existing userland into the new jail.&lt;br /&gt;
&lt;br /&gt;
# make buildworld&lt;br /&gt;
&lt;br /&gt;
This command will populate the directory subtree chosen as jail's physical location on the file system with the necessary binaries, libraries, manual pages and so on.&lt;br /&gt;
&lt;br /&gt;
# make installworld DESTDIR=/home/jail/read-only/root&lt;br /&gt;
&lt;br /&gt;
The distribution target for make installs every needed configuration file. In simple words, it installs every installable file of /usr/src/etc/ to the /etc directory of the jail environment: /home/jail/THE_JAIL_NAME/etc/.&lt;br /&gt;
&lt;br /&gt;
# make distribution DESTDIR=/home/jail/read-only/root&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Next, prepare a FreeBSD Ports Collection for the jails as well as a FreeBSD source tree, which is required for mergemaster:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# mkdir /home/jail/read-only/root/usr/ports&lt;br /&gt;
# portsnap -p /home/jail/read-only/root/usr/ports fetch extract&lt;br /&gt;
# portsnap -p /home/jail/read-only/root/usr/ports fetch update&lt;br /&gt;
# cpdup /usr/src /home/jail/read-only/root/usr/src&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Setup for Drupal:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /home/jail/read-only/root&lt;br /&gt;
# mkdir www&lt;br /&gt;
# cd www&lt;br /&gt;
# fetch http://ftp.drupal.org/files/projects/drupal-6.22.tar.gz&lt;br /&gt;
# tar zxvf drupal-6.22.tar.gz&lt;br /&gt;
# mv drupal-6.22 drupal6&lt;br /&gt;
# chown -R root:wheel drupal6&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create a skeleton for the read-write portion of the system:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# mkdir /home/jail/read-only/skel&lt;br /&gt;
# mkdir /home/jail/read-only/skel/home&lt;br /&gt;
# mkdir /home/jail/read-only/skel/usr-X11R6&lt;br /&gt;
# mkdir /home/jail/read-only/skel/distfiles&lt;br /&gt;
&lt;br /&gt;
??? # mkdir /home/jail/read-only/skel/drupal-sites&lt;br /&gt;
??? # mkdir /home/jail/read-only/skel/drupal-files&lt;br /&gt;
&lt;br /&gt;
# cd /home/jail/read-only/root&lt;br /&gt;
# mv etc /home/jail/read-only/skel&lt;br /&gt;
# mv usr/local /home/jail/read-only/skel/usr-local&lt;br /&gt;
# mv tmp /home/jail/read-only/skel&lt;br /&gt;
# mv var /home/jail/read-only/skel&lt;br /&gt;
# mv root /home/jail/read-only/skel&lt;br /&gt;
&lt;br /&gt;
# mv www/drupal6/sites /home/jail/read-only/skel/drupal-sites&lt;br /&gt;
&lt;br /&gt;
Use mergemaster to install missing configuration files. Then get rid of the extra directories that mergemaster creates:&lt;br /&gt;
&lt;br /&gt;
# mergemaster -t /home/jail/read-only/skel/var/tmp/temproot -D /home/jail/read-only/skel -i&lt;br /&gt;
How should I handle ./.cshrc? [Leave it to install later] enter&lt;br /&gt;
How should I handle ./.profile? [Leave it to install later] enter&lt;br /&gt;
...&lt;br /&gt;
keep pressing space until you see end : q&lt;br /&gt;
&lt;br /&gt;
*** You installed a login.conf file, so make sure that you run&lt;br /&gt;
'/usr/bin/cap_mkdb /home/jail/read-only/skel/etc/login.conf'&lt;br /&gt;
to rebuild your login.conf database&lt;br /&gt;
&lt;br /&gt;
Would you like to run it now? y or n [n] y&lt;br /&gt;
&lt;br /&gt;
*** You installed a services file, so make sure that you run&lt;br /&gt;
'/usr/sbin/services_mkdb -q -o /home/jail/read-only/skel/var/db/services.db /home/jail/read-only/skel/etc/services'&lt;br /&gt;
to rebuild your services database&lt;br /&gt;
&lt;br /&gt;
Would you like to run it now? y or n [n] y&lt;br /&gt;
&lt;br /&gt;
*** You installed a new master.passwd file, so make sure that you run&lt;br /&gt;
'/usr/sbin/pwd_mkdb -d /home/jail/read-only/skel/etc -p /home/jail/read-only/skel/etc/master.passwd'&lt;br /&gt;
to rebuild your password files&lt;br /&gt;
&lt;br /&gt;
Would you like to run it now? y or n [n] y&lt;br /&gt;
&lt;br /&gt;
# cd /home/jail/read-only/skel&lt;br /&gt;
# rm -R bin boot lib libexec mnt proc rescue sbin sys usr dev&lt;br /&gt;
&lt;br /&gt;
Now, symlink the read-write file system to the read-only file system. Please make sure that the symlinks are created in the correct s/ locations. Real directories or the creation of directories in the wrong locations will cause the installation to fail.&lt;br /&gt;
&lt;br /&gt;
# cd /home/jail/read-only/root&lt;br /&gt;
# mkdir s&lt;br /&gt;
# ln -s s/etc etc&lt;br /&gt;
# ln -s s/home home&lt;br /&gt;
# ln -s s/root root&lt;br /&gt;
# ln -s ../s/usr-local usr/local&lt;br /&gt;
# ln -s ../s/usr-X11R6 usr/X11R6&lt;br /&gt;
# ln -s ../../s/distfiles usr/ports/distfiles&lt;br /&gt;
# ln -s s/tmp tmp&lt;br /&gt;
# ln -s s/var var&lt;br /&gt;
&lt;br /&gt;
# ln -s s/home/cwn_www/nginx www&lt;br /&gt;
# ln -s s/home/cwn_www/scripts scripts&lt;br /&gt;
&lt;br /&gt;
??? # ln -s ../../s/drupal-sites www/drupal6/sites&lt;br /&gt;
??? # ln -s ../../../../s/drupal-files www/drupal6/sites/default/files&lt;br /&gt;
&lt;br /&gt;
??? Changing the directory permission&lt;br /&gt;
??? # find /home/jail -type d -print0 | xargs -0 -I @ sh -c 'chmod 700 @ ; chown root:wheel @'&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;As a last step, create a generic /home/jail/read-only/skel/etc/make.conf with its contents as shown below:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# echo 'WRKDIRPREFIX?= /s/portbuild' &amp;gt;&amp;gt; /home/jail/read-only/skel/etc/make.conf&lt;br /&gt;
&lt;br /&gt;
Having WRKDIRPREFIX set up this way will make it possible to compile FreeBSD ports inside each jail. Remember that the ports directory is part of the read-only system. The custom path for WRKDIRPREFIX allows builds to be done in the read-write portion of every jail.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating Jails:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Now that we have a complete FreeBSD jail template, we can setup and configure the jails in /etc/rc.conf. This example demonstrates the creation of 3 jails: "NS", "MAIL" and "WWW".&lt;br /&gt;
&lt;br /&gt;
Put the following lines into the /etc/fstab file, so that the read-only template for the jails and the read-write space will be available in the respective jails:&lt;br /&gt;
&lt;br /&gt;
# vim /etc/fstab&lt;br /&gt;
### read-only partitions&lt;br /&gt;
/home/jail/read-only/root   /home/jail/read-only/ns     nullfs  ro  0   0&lt;br /&gt;
/home/jail/read-only/root   /home/jail/read-only/mail   nullfs  ro  0   0&lt;br /&gt;
/home/jail/read-only/root   /home/jail/read-only/www    nullfs  ro  0   0&lt;br /&gt;
&lt;br /&gt;
### read-write partitions&lt;br /&gt;
/home/jail/read-write/ns     /home/jail/read-only/ns/s   nullfs  rw  0   0&lt;br /&gt;
/home/jail/read-write/mail   /home/jail/read-only/mail/s nullfs  rw  0   0&lt;br /&gt;
/home/jail/read-write/www    /home/jail/read-only/www/s  nullfs  rw  0   0&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; Partitions marked with a 0 pass number are not checked by fsck(8) during boot, and partitions marked with a 0 dump number are not backed up by dump(8). We do not want fsck to check nullfs mounts or dump to back up the read-only nullfs mounts of the jails. This is why they are marked with "0 0" in the last two columns of each fstab entry above.&lt;br /&gt;
&lt;br /&gt;
# vim /etc/rc.conf&lt;br /&gt;
&lt;pre&gt;### for jail host
ifconfig_re0="inet 192.168.0.1  netmask 255.255.255.0"

### for jail guests
ifconfig_re0_alias0="inet 192.168.0.2 netmask 255.255.255.255"
ifconfig_re0_alias1="inet 192.168.0.3 netmask 255.255.255.255"
ifconfig_re0_alias2="inet 192.168.0.4 netmask 255.255.255.255"

### jail settings
jail_enable="YES"                   # Set to NO to disable starting of any jails
jail_set_hostname_allow="NO"        # Allow root user in a jail to change its hostname
#jail_socket_unixiproute_only="YES" # Route only TCP/IP within a jail
jail_list="ns mail www"             # Space separated list of names of jails
                                    # Note: Jail names in jail_list should contain alphanumeric characters only.

### j-ns
jail_ns_hostname="j-ns.local"                  # jail's hostname
jail_ns_ip="192.168.0.2"                 # jail's IP address
jail_ns_rootdir="/home/jail/read-only/ns" # jail's root directory
jail_ns_devfs_enable="YES"               # mount devfs in the jail
jail_ns_devfs_ruleset="ns_ruleset"       # devfs ruleset to apply to jail

### j-mail
jail_mail_hostname="j-mail.local"                  # jail's hostname
jail_mail_ip="192.168.0.3"                   # jail's IP address
jail_mail_rootdir="/home/jail/read-only/mail" # jail's root directory
jail_mail_devfs_enable="YES"                 # mount devfs in the jail
jail_mail_devfs_ruleset="mail_ruleset"       # devfs ruleset to apply to jail

### j-www
jail_www_hostname="j-www.local"                  # jail's hostname
jail_www_ip="192.168.0.4"                  # jail's IP address
jail_www_rootdir="/home/jail/read-only/www" # jail's root directory
jail_www_devfs_enable="YES"                # mount devfs in the jail
jail_www_devfs_ruleset="www_ruleset"       # devfs ruleset to apply to jail
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; The jail_name_rootdir variable must not be set to a path which includes a symbolic link, otherwise the jails will refuse to start. Use the realpath(1) utility to determine a value which should be set to this variable. Please see the FreeBSD-SA-07:01.jail Security Advisory for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; for devfs ruleset, cat /etc/defaults/devfs.rules.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make sure your jail host has all the IP addresses for jail guests:&lt;/b&gt;&lt;br /&gt;
# /etc/rc.d/netif restart &amp;amp;&amp;amp; /etc/rc.d/routing restart&lt;br /&gt;
# ifconfig&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Create the required mount points for the read-only file system of each jail:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /home/jail/read-only&lt;br /&gt;
# mkdir ns mail www&lt;br /&gt;
??? # chmod 700 ns mail www&lt;br /&gt;
??? # chown root:wheel ns mail www&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Install the read-write template into each jail. Note the use of sysutils/cpdup, which helps to ensure that a correct copy is done of each directory:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cpdup /home/jail/read-only/skel /home/jail/read-write/ns&lt;br /&gt;
# cpdup /home/jail/read-only/skel /home/jail/read-write/mail&lt;br /&gt;
# cpdup /home/jail/read-only/skel /home/jail/read-write/www&lt;br /&gt;
&lt;br /&gt;
In this phase, the jails are built and prepared to run. First, mount the required file systems for each jail, and then start them using the /etc/rc.d/jail script:&lt;br /&gt;
&lt;br /&gt;
# mount -a&lt;br /&gt;
# df -h&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Start a specific jail:&lt;/b&gt;&lt;br /&gt;
# /etc/rc.d/jail start ns&lt;br /&gt;
# /etc/rc.d/jail start mail&lt;br /&gt;
# /etc/rc.d/jail start www&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Start all jails:&lt;/b&gt;&lt;br /&gt;
# /etc/rc.d/jail start&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Stop a specific jail:&lt;/b&gt;&lt;br /&gt;
# /etc/rc.d/jail stop www&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A clean way to shut down a jail(8) is not available at the moment. This is because commands normally used to accomplish a clean system shutdown cannot be used inside a jail. The best way to shut down a jail is to run the following command from within the jail itself or using the jexec(8) utility from outside the jail:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
j-www # sh /etc/rc.shutdown&lt;br /&gt;
or&lt;br /&gt;
# jexec 2 shutdown -p now&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The jails should be running now. To check if they have started correctly, use the jls(8) command. Its output should be similar to the following:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# jls&lt;br /&gt;
JID  IP Address      Hostname                      Path&lt;br /&gt;
7  192.168.0.2 j-ns                          /home/jail/read-only/ns&lt;br /&gt;
8  192.168.0.3 j-mail                        /home/jail/read-only/mail&lt;br /&gt;
9  192.168.0.4 j-www                         /home/jail/read-only/www&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;At this point, it should be possible to log onto each jail, add new users or configure daemons. The JID column indicates the jail identification number of each running jail. Use the following command in order to perform administrative tasks in the jail whose JID is 9:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# jexec 9 tcsh&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Use google's public DNS server as a DNS resolver:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
j-www # vi /etc/resolv.conf&lt;br /&gt;
nameserver 8.8.8.8&lt;br /&gt;
nameserver 8.8.4.4&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Modify /etc/rc.conf:&lt;/b&gt;&lt;br /&gt;
j-www # vi /etc/rc.conf&lt;br /&gt;
### enable syslogd, no network socket will be opened for syslogd&lt;br /&gt;
syslogd_enable="YES"&lt;br /&gt;
syslogd_flags="-s -s"&lt;br /&gt;
&lt;br /&gt;
### SendMail&lt;br /&gt;
sendmail_enable="NO"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Modify /etc/hosts:&lt;/b&gt;&lt;br /&gt;
j-www # vim /etc/hosts&lt;br /&gt;
::1     localhost localhost.j-www.local&lt;br /&gt;
127.0.0.1   localhost localhost.j-www.local&lt;br /&gt;
&lt;br /&gt;
192.168.100.34 j-www.local j-www&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;To fix this error "hash map "Alias0": missing map file /etc/mail/aliases.db in FreeBSD jail":&lt;/b&gt;&lt;br /&gt;
# sendmail -bi&lt;br /&gt;
# ls -l /etc/mail/aliases.db&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Note:&lt;/b&gt; you must edit /etc/hosts before running sendmail -bi command.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Comment out adjkerntz in crontab:&lt;/b&gt;&lt;br /&gt;
j-www # vim /etc/crontab&lt;br /&gt;
#1,31    0-5     *       *       *       root    adjkerntz -a&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;SVN server setup&lt;/b&gt;&lt;br /&gt;
# cd /usr/ports/devel/subversion&lt;br /&gt;
# make install clean&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make sure you DO uncheck this option:&lt;/b&gt;&lt;br /&gt;
&lt;span style="color: blue;"&gt;[] BDB=off "db4 repository backend"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
# mv /usr/local/bin/svn /usr/local/bin/svn.orig&lt;br /&gt;
&lt;br /&gt;
# vi /usr/local/bin/svn&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: blue;"&gt;
#!/bin/sh

### initialize
svnarg=""

### use encoding utf-8 as default if run "svn ci" or "svn commit".
if [ "$1" != "help" ]; then
  for myarg in "$@"; do
    if [ "${myarg}" = "commit" ] || [ "${myarg}" = "ci" ]; then
      svnarg="--encoding utf-8"
      break
    fi
  done
fi

### wrapper script to set umask to 027 on subversion binaries
### Note: the meaning of each umask:
### umask 002 // File permission 644. Owner can read/write. Group and Others can only read.
### umask 007 // File permission 660. Owner and Group can read/write. Others can not read or write.
### umask 027 // File permission 640. Owner can read/write. Group can read. Others can not read or write.
umask 027

### svn command
/usr/local/bin/svn.orig ${svnarg} "$@"
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
Don't forget to make your wrapper script executable:&lt;br /&gt;
&lt;br /&gt;
# chmod +x /usr/local/bin/svn&lt;br /&gt;
&lt;br /&gt;
# mkdir /home/jail/svn-rep&lt;br /&gt;
# cd /home/jail/svn-rep&lt;br /&gt;
# svnadmin create ns&lt;br /&gt;
# svnadmin create mail&lt;br /&gt;
# svnadmin create www&lt;br /&gt;
&lt;br /&gt;
# vi www/conf/svnserve.conf&lt;br /&gt;
[general]&lt;br /&gt;
anon-access = none&lt;br /&gt;
auth-access = write&lt;br /&gt;
password-db = passwd&lt;br /&gt;
&lt;br /&gt;
# vi www/conf/passwd&lt;br /&gt;
[users]&lt;br /&gt;
danny = mypassword&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Start SVN server as a stand-alone daemon&lt;/span&gt;&lt;br /&gt;
# /usr/local/bin/svnserve -d --listen-port=3690 --listen-host=0.0.0.0 -r /home/jail/svn-rep&lt;br /&gt;
&lt;br /&gt;
# vi /etc/rc.conf&lt;br /&gt;
### SVN&lt;br /&gt;
svnserve_enable="YES"&lt;br /&gt;
svnserve_flags="-d --listen-port=3690 --listen-host=0.0.0.0"&lt;br /&gt;
svnserve_data="/home/jail/svn-rep"&lt;br /&gt;
svnserve_user="root"&lt;br /&gt;
svnserve_group="wheel"&lt;br /&gt;
&lt;br /&gt;
# svn import /home/jail/read-only/skel/drupal-sites/all file:///home/jail/svn-rep/www -m "initial import"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;SVN client setup&lt;/b&gt;&lt;br /&gt;
# rm -r /www/drupal6/sites/all/*&lt;br /&gt;
# svn checkout svn://192.168.0.1/www /www/drupal6/sites/all&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;sending mail through sendmail inside a jail:&lt;/b&gt;&lt;br /&gt;
# cat mail.php&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
mail('test@example.com', 'My Subject', 'my msg');&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# php mail.php&lt;br /&gt;
collect: Cannot write ./dfpA4NVE5H097195 (bfcommit, uid=25, gid=25): Permission denied&lt;br /&gt;
queueup: cannot create queue file ./qfpA4NVE5H097195, euid=25, fd=-1, fp=0x0: Permission denied&lt;br /&gt;
&lt;br /&gt;
# chown smmsp:smmsp /var/spool/clientmqueue&lt;br /&gt;
# chmod 770 /var/spool/clientmqueue&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fine Tuning and Administration&lt;/b&gt;&lt;br /&gt;
There are several options which can be set for any jail, and various ways of combining a host FreeBSD system with jails, to produce higher level applications. This section presents:&lt;br /&gt;
&lt;br /&gt;
Some of the options available for tuning the behavior and security restrictions implemented by a jail installation.&lt;br /&gt;
&lt;br /&gt;
Some of the high-level applications for jail management, which are available through the FreeBSD Ports Collection, and can be used to implement overall jail-based solutions.&lt;br /&gt;
&lt;br /&gt;
Fine tuning of a jail's configuration is mostly done by setting sysctl(8) variables. A special subtree of sysctl exists as a basis for organizing all the relevant options: the security.jail.* hierarchy of FreeBSD kernel options. Here is a list of the main jail-related sysctls, complete with their default value. Names should be self-explanatory, but for more information about them, please refer to the jail(8) and sysctl(8) manual pages.&lt;br /&gt;
&lt;br /&gt;
security.jail.set_hostname_allowed: 1&lt;br /&gt;
&lt;br /&gt;
security.jail.socket_unixiproute_only: 1&lt;br /&gt;
&lt;br /&gt;
security.jail.sysvipc_allowed: 0&lt;br /&gt;
&lt;br /&gt;
security.jail.enforce_statfs: 2&lt;br /&gt;
&lt;br /&gt;
security.jail.allow_raw_sockets: 0&lt;br /&gt;
&lt;br /&gt;
security.jail.chflags_allowed: 0&lt;br /&gt;
&lt;br /&gt;
security.jail.jailed: 0&lt;br /&gt;
&lt;br /&gt;
These variables can be used by the system administrator of the host system to add or remove some of the limitations imposed by default on the root user. Note that there are some limitations which cannot be removed. The root user is not allowed to mount or unmount file systems from within a jail(8). The root inside a jail may not load or unload devfs(8) rulesets, set firewall rules, or do many other administrative tasks which require modifications of in-kernel data, such as setting the securelevel of the kernel.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ping from jail not permitted error&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
ICMP is disallowed by defaut for jails, see the sysctl :&lt;br /&gt;
&lt;br /&gt;
# echo security.jail.allow_raw_sockets=1 &amp;gt;&amp;gt; /etc/sysctl.conf&lt;br /&gt;
&lt;br /&gt;
Now restart your jails and the problem should be fixed.&lt;br /&gt;
&lt;br /&gt;
There are good reasons for this default, so if you test remember to set it back when you are done.&lt;br /&gt;
&lt;br /&gt;
Also, on a point of style, jails in their current form (see VIMAGE) do not get a network stack of their own so they don't have a firewall but share the hosts' network and firewall, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Cannot remove files inside a jail directory&lt;/b&gt;&lt;br /&gt;
override r-sr-xr-x  root/wheel schg for j/mroot/bin/rcp? y&lt;br /&gt;
rm: j/mroot/bin/rcp: Operation not permitted&lt;br /&gt;
rm: j/mroot/bin: Directory not empty&lt;br /&gt;
override r--r--r--  root/wheel schg for j/mroot/lib/libc.so.7? y&lt;br /&gt;
rm: j/mroot/lib/libc.so.7: Operation not permitted&lt;br /&gt;
&lt;br /&gt;
# chflags -R noschg /home/jail/read-write/ns&lt;br /&gt;
# rm -r /home/jail/read-write/ns&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;High-level administrative tools in FreeBSD Ports Collection&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/sysutils/jailutils ; make install clean&lt;br /&gt;
&lt;br /&gt;
# cd /usr/ports/sysutils/ezjail ; make install clean&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2012/01/install-jails-on-freebsd-82.html"&gt;http://gala4th.blogspot.com/2012/01/install-jails-on-freebsd-82.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/jails.html"&gt;http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/jails.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
VIMAGE - Better virtualization in FreeBSD 8&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/10/vimage-better-virtualization-in-freebsd.html"&gt;http://gala4th.blogspot.com/2011/10/vimage-better-virtualization-in-freebsd.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
FreeBSD 8 VIMAGE + epair howto&lt;br /&gt;
&lt;a href="http://gala4th.blogspot.com/2011/10/freebsd-8-vimage-epair-howto.html"&gt;http://gala4th.blogspot.com/2011/10/freebsd-8-vimage-epair-howto.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Creating a FreeBSD Jail&lt;br /&gt;
&lt;a href="http://www.section6.net/wiki/index.php/Creating_a_FreeBSD_Jail"&gt;http://www.section6.net/wiki/index.php/Creating_a_FreeBSD_Jail&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2361800974999510068-8817873656609320635?l=blog.ijun.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ThereIsNoPlaceLike127001/~4/uiTyM3cYflo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.ijun.org/feeds/8817873656609320635/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2361800974999510068&amp;postID=8817873656609320635" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/8817873656609320635?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2361800974999510068/posts/default/8817873656609320635?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ThereIsNoPlaceLike127001/~3/uiTyM3cYflo/install-jails-on-freebsd-82.html" title="Install Jails on FreeBSD 8.2" /><author><name>Jun Hsieh</name><uri>http://www.blogger.com/profile/12582710063814556713</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.ijun.org/2012/01/install-jails-on-freebsd-82.html</feedburner:origLink></entry></feed>

