HowTo to handle SVN repositories creation and access control with Redmine » History » Version 24

Eugenio Piasini, 2013-01-10 15:40

1 22 Art Kuo
h1. HowTo to handle SVN repositories creation and access control with Redmine (part 1, deprecated)
2 1 Jean-Philippe Lang
3 21 Art Kuo
*This setup is deprecated, you should try [[HowTo Automate repository creation]] and [[Repositories_access_control_with_apache_mod_dav_svn_and_mod_perl]]*
4 18 Knight Samar
5 2 Jean-Philippe Lang
{{>TOC}}
6 17 Nicolas Chuche
7 17 Nicolas Chuche
8 1 Jean-Philippe Lang
h2. Overview
9 1 Jean-Philippe Lang
10 1 Jean-Philippe Lang
*This setup is not required if you just need to browse your repositories and changesets from Redmine.*
11 1 Jean-Philippe Lang
12 1 Jean-Philippe Lang
As of version 0.5.0, Redmine is able to handle Subversion repositories creation and access control.
13 1 Jean-Philippe Lang
14 24 Eugenio Piasini
Once you've done this extra setup, Redmine will create the repository for each of your projects. Users will be allowed to access the repositories using ssh+svn, according to their permissions defined in Redmine:
15 1 Jean-Philippe Lang
16 1 Jean-Philippe Lang
* for public projects : read access to the repository for any user, write access for project members only,
17 1 Jean-Philippe Lang
* for private projects : read/write access allowed to project members only.
18 1 Jean-Philippe Lang
19 8 Jean-Philippe Lang
User authentication is done using the same login/password as for Redmine access.
20 1 Jean-Philippe Lang
21 1 Jean-Philippe Lang
h2. Requirements
22 1 Jean-Philippe Lang
23 1 Jean-Philippe Lang
h3. Software
24 1 Jean-Philippe Lang
25 1 Jean-Philippe Lang
You need Redmine 0.5.0 or higher, running with MySQL[1].
26 1 Jean-Philippe Lang
27 5 Jean-Philippe Lang
Your SVN repositories must be hosted on a *nix system with the following packages:
28 5 Jean-Philippe Lang
* nss_mysql
29 19 Eugenio Piasini
* pam_mysql 0.7pre2 or higher, compiled with SHA1 support (note that if using Redmine >= 1.2, due to the use of "salt" when storing hashed passwords, pam_mysql has to be patched with AxeldV's "patch":http://www.redmine.org/boards/2/topics/24383?r=26204#message-26204)
30 1 Jean-Philippe Lang
31 1 Jean-Philippe Lang
Scripts used in this HowTo can be found in the /extra/svn directory of Redmine.
32 1 Jean-Philippe Lang
33 5 Jean-Philippe Lang
In this HowTo, we assume that:
34 5 Jean-Philippe Lang
* the redmine database is called @redmine@ and hosted on @localhost@
35 5 Jean-Philippe Lang
* the Subversion repositories are located in @/var/svn@
36 5 Jean-Philippe Lang
37 1 Jean-Philippe Lang
h3. Network considerations
38 1 Jean-Philippe Lang
39 5 Jean-Philippe Lang
The SVN host must be able to access both the Redmine database and HTTP server(s). In many cases, they will all be located on the same host.
40 1 Jean-Philippe Lang
41 1 Jean-Philippe Lang
h2. Setup
42 1 Jean-Philippe Lang
43 5 Jean-Philippe Lang
h3. Installing requires packages
44 5 Jean-Philippe Lang
45 5 Jean-Philippe Lang
Get nss_mysql and other necessary packages:
46 5 Jean-Philippe Lang
47 14 Jean-Philippe Lang
  apt-get install build-essential libnss-mysql libpam0g-dev libssl-dev libmysqlclient15-dev
48 5 Jean-Philippe Lang
49 5 Jean-Philippe Lang
Get and build @pam_mysql@:
50 5 Jean-Philippe Lang
51 5 Jean-Philippe Lang
<pre>
52 5 Jean-Philippe Lang
$ cd /usr/src
53 5 Jean-Philippe Lang
$ wget http://prdownloads.sourceforge.net/pam-mysql/pam_mysql-0.7RC1.tar.gz
54 5 Jean-Philippe Lang
$ tar xzf pam_mysql-0.7RC1.tar.gz
55 5 Jean-Philippe Lang
$ cd pam_mysql-0.7RC1
56 5 Jean-Philippe Lang
$ ./configure --with-openssl
57 5 Jean-Philippe Lang
$ make && make install
58 5 Jean-Philippe Lang
</pre>
59 5 Jean-Philippe Lang
60 1 Jean-Philippe Lang
h3. Preparing the Redmine database
61 1 Jean-Philippe Lang
62 1 Jean-Philippe Lang
Some views need to be added to the Redmine database. These views are used to authenticate users and retrieve their permissions.
63 1 Jean-Philippe Lang
64 23 Eugenio Piasini
1. Create the different views in your Redmine database:
65 1 Jean-Philippe Lang
66 7 Jean-Philippe Lang
  mysql --user=root redmine -p < create_views.sql
67 1 Jean-Philippe Lang
68 7 Jean-Philippe Lang
2. Create and grant privileges to 2 new mysql users (@redmine_nss@ and @redmine_pam@):
69 1 Jean-Philippe Lang
70 1 Jean-Philippe Lang
<pre>
71 7 Jean-Philippe Lang
mysql --user=root -p
72 1 Jean-Philippe Lang
mysql> create user redmine_nss@localhost identified by 'averylongpassword';
73 1 Jean-Philippe Lang
mysql> grant SELECT on redmine.nss_groups to redmine_nss@localhost;
74 1 Jean-Philippe Lang
mysql> grant SELECT on redmine.nss_users to redmine_nss@localhost;
75 1 Jean-Philippe Lang
mysql> grant SELECT on redmine.nss_grouplist to redmine_nss@localhost;
76 4 Jean-Philippe Lang
mysql> create user redmine_pam@localhost identified by 'averylongpassword';
77 4 Jean-Philippe Lang
mysql> grant SELECT on redmine.ssh_users to redmine_pam@localhost;
78 1 Jean-Philippe Lang
</pre>
79 1 Jean-Philippe Lang
80 8 Jean-Philippe Lang
h3. Configuring nss-mysql
81 1 Jean-Philippe Lang
82 1 Jean-Philippe Lang
3. Create the /etc/nss-mysql.conf as follows:
83 1 Jean-Philippe Lang
84 1 Jean-Philippe Lang
<pre>
85 1 Jean-Philippe Lang
conf.version = 2;
86 1 Jean-Philippe Lang
users.host = inet:localhost:3306;
87 1 Jean-Philippe Lang
users.database = redmine;
88 1 Jean-Philippe Lang
users.db_user = redmine_nss;
89 4 Jean-Philippe Lang
users.db_password = averylongpassword;
90 1 Jean-Philippe Lang
users.backup_database = nss_mysql_backup;
91 1 Jean-Philippe Lang
users.table = nss_users;
92 1 Jean-Philippe Lang
users.user_column = nss_users.username;
93 9 Jean-Philippe Lang
users.userid_column = nss_users.username;
94 1 Jean-Philippe Lang
users.uid_column = nss_users.uid;
95 1 Jean-Philippe Lang
users.gid_column = 100;
96 1 Jean-Philippe Lang
users.realname_column = nss_users.realname;
97 1 Jean-Philippe Lang
users.homedir_column = "/false/path";
98 1 Jean-Philippe Lang
users.shell_column = "/usr/local/bin/svnserve.wrapper";
99 1 Jean-Philippe Lang
groups.group_info_table = nss_groups;
100 1 Jean-Philippe Lang
groups.group_name_column = nss_groups.name;
101 1 Jean-Philippe Lang
groups.groupid_column = nss_groups.gid;
102 1 Jean-Philippe Lang
groups.gid_column = nss_groups.gid;
103 1 Jean-Philippe Lang
groups.password_column = "x";
104 1 Jean-Philippe Lang
groups.members_table = nss_grouplist;
105 1 Jean-Philippe Lang
groups.member_userid_column = nss_grouplist.username;
106 1 Jean-Philippe Lang
groups.member_groupid_column = nss_grouplist.gid;
107 1 Jean-Philippe Lang
</pre>
108 1 Jean-Philippe Lang
109 1 Jean-Philippe Lang
4. Install the svnserve wrapper
110 1 Jean-Philippe Lang
111 1 Jean-Philippe Lang
  sudo install svnserve.wrapper /usr/local/bin
112 1 Jean-Philippe Lang
113 4 Jean-Philippe Lang
5. Change /etc/nsswitch.conf
114 1 Jean-Philippe Lang
115 24 Eugenio Piasini
Add “mysql” at the end of the two lines passwd and group like that:
116 1 Jean-Philippe Lang
117 1 Jean-Philippe Lang
<pre>
118 1 Jean-Philippe Lang
passwd:         compat mysql
119 1 Jean-Philippe Lang
group:          compat mysql
120 1 Jean-Philippe Lang
</pre>
121 1 Jean-Philippe Lang
122 1 Jean-Philippe Lang
6. Test that all this stuff works :
123 1 Jean-Philippe Lang
124 1 Jean-Philippe Lang
You must have users in some project to verify.
125 1 Jean-Philippe Lang
126 1 Jean-Philippe Lang
<pre>
127 1 Jean-Philippe Lang
% getent passwd
128 1 Jean-Philippe Lang
[...]
129 1 Jean-Philippe Lang
user1:x:5002:100:user1 user1:/false/path:/usr/local/bin/svnserve.wrapper
130 1 Jean-Philippe Lang
user2:x:5003:100:user2 user2:/false/path:/usr/local/bin/svnserve.wrapper
131 1 Jean-Philippe Lang
132 1 Jean-Philippe Lang
% getent group
133 1 Jean-Philippe Lang
[...]
134 5 Jean-Philippe Lang
project1:x:5001:
135 5 Jean-Philippe Lang
project2:x:5002:
136 1 Jean-Philippe Lang
</pre>
137 1 Jean-Philippe Lang
138 1 Jean-Philippe Lang
h3. Authorize ssh pam to use mysql
139 1 Jean-Philippe Lang
140 4 Jean-Philippe Lang
7. Add these lines in @/etc/pam.d/ssh@ :
141 1 Jean-Philippe Lang
142 4 Jean-Philippe Lang
<pre>
143 4 Jean-Philippe Lang
auth sufficient pam_mysql.so \
144 4 Jean-Philippe Lang
verbose=1 \
145 4 Jean-Philippe Lang
user=redmine_pam \
146 4 Jean-Philippe Lang
passwd=averylongpassword \
147 4 Jean-Philippe Lang
host=localhost \
148 4 Jean-Philippe Lang
db=redmine \
149 4 Jean-Philippe Lang
table=ssh_users \
150 4 Jean-Philippe Lang
usercolumn=username \
151 4 Jean-Philippe Lang
passwdcolumn=password crypt=4
152 1 Jean-Philippe Lang
153 4 Jean-Philippe Lang
account sufficient pam_mysql.so \
154 4 Jean-Philippe Lang
verbose=1 \
155 4 Jean-Philippe Lang
user=redmine_pam \
156 4 Jean-Philippe Lang
passwd=averylongpassword \
157 4 Jean-Philippe Lang
host=localhost \
158 4 Jean-Philippe Lang
db=redmine \
159 4 Jean-Philippe Lang
table=ssh_users \
160 4 Jean-Philippe Lang
usercolumn=username \
161 4 Jean-Philippe Lang
passwdcolumn=password crypt=4
162 4 Jean-Philippe Lang
163 4 Jean-Philippe Lang
password sufficient pam_mysql.so \
164 4 Jean-Philippe Lang
verbose=1 \
165 4 Jean-Philippe Lang
user=redmine_pam \
166 4 Jean-Philippe Lang
passwd=averylongpassword \
167 4 Jean-Philippe Lang
host=localhost \
168 4 Jean-Philippe Lang
db=redmine \
169 4 Jean-Philippe Lang
table=ssh_users \
170 1 Jean-Philippe Lang
usercolumn=username \
171 1 Jean-Philippe Lang
passwdcolumn=password crypt=4
172 1 Jean-Philippe Lang
</pre>
173 1 Jean-Philippe Lang
174 1 Jean-Philippe Lang
Juste before
175 1 Jean-Philippe Lang
176 1 Jean-Philippe Lang
  @include common-auth
177 1 Jean-Philippe Lang
178 1 Jean-Philippe Lang
8. Test this against an existing Redmine user
179 1 Jean-Philippe Lang
180 6 Jean-Philippe Lang
Try to connect to the SVN host using a Redmine username (eg. jsmith):
181 1 Jean-Philippe Lang
182 6 Jean-Philippe Lang
<pre>
183 6 Jean-Philippe Lang
$ ssh jsmith@localhost
184 6 Jean-Philippe Lang
jsmith@localhost's password:
185 6 Jean-Philippe Lang
Could not chdir to home directory /false/path: No such file or directory
186 6 Jean-Philippe Lang
( success ( 1 2 ( ANONYMOUS EXTERNAL ) ( edit-pipeline ) ) )
187 6 Jean-Philippe Lang
</pre>
188 6 Jean-Philippe Lang
189 6 Jean-Philippe Lang
The chdir error is the expected result.
190 1 Jean-Philippe Lang
191 1 Jean-Philippe Lang
h3. Automating repository creation
192 1 Jean-Philippe Lang
193 8 Jean-Philippe Lang
Repository creation can be automated by running periodically the reposman script.
194 1 Jean-Philippe Lang
195 5 Jean-Philippe Lang
It takes 2 arguments:
196 1 Jean-Philippe Lang
197 5 Jean-Philippe Lang
    * @svn-dir@: path to the directory where your svn repositories are located
198 1 Jean-Philippe Lang
    * @redmine-host@: host name of your Redmine install
199 1 Jean-Philippe Lang
200 15 Nicolas Chuche
Perl and Ruby versions of this script are provided but the perl version is now deprecated.
201 1 Jean-Philippe Lang
202 8 Jean-Philippe Lang
Example using the Ruby version:
203 8 Jean-Philippe Lang
204 1 Jean-Philippe Lang
<pre>
205 15 Nicolas Chuche
./reposman.rb --svn-dir=/var/svn --redmine-host=localhost
206 1 Jean-Philippe Lang
repository /var/svn/project2 created
207 1 Jean-Philippe Lang
repository /var/svn/project1 created
208 1 Jean-Philippe Lang
mode change on /var/svn/project3
209 1 Jean-Philippe Lang
</pre>
210 1 Jean-Philippe Lang
211 1 Jean-Philippe Lang
Projects are retrieved from Redmine using a SOAP web service. This web service is disabled by default in Redmine.
212 16 Jean-Philippe Lang
To enable it, go to “Administration -> Settings” and check *Enable WS for repository management*.
213 1 Jean-Philippe Lang
214 13 Nicolas Chuche
Make sure this option is checked if you get this error when running reposman:
215 13 Nicolas Chuche
@Service description 'http://localhost/sys/service.wsdl' can't be loaded: 404 Not Found@
216 13 Nicolas Chuche
217 12 Nicolas Chuche
With a recent version of redMine/reposman.rb (re. 860 and later), reposman.rb can register the new repository
218 1 Jean-Philippe Lang
in redMine so that you have nothing to do and set the owner of repository to who you want to allow browsing private
219 15 Nicolas Chuche
repository in redMine. You can do that by using the @--url@ argument :
220 1 Jean-Philippe Lang
221 15 Nicolas Chuche
<pre>
222 15 Nicolas Chuche
ruby ./reposman.rb --redmine-host localhost:3000 --svn-dir /var/svn \
223 15 Nicolas Chuche
                   --url file:///var/svn/
224 15 Nicolas Chuche
</pre>
225 15 Nicolas Chuche
226 15 Nicolas Chuche
reposman will send back to Redmine the url of your repository. *be careful* when testing, one registered, you can't change the url in redmine).
227 15 Nicolas Chuche
228 15 Nicolas Chuche
Next time you create a project, reposman will informe Redmine that the repository was created and Redmine will save the repository url.
229 15 Nicolas Chuche
This way, the administrator won't have to enter the repositories urls manually in Redmine.
230 15 Nicolas Chuche
231 5 Jean-Philippe Lang
h3. Accessing the repositories
232 5 Jean-Philippe Lang
233 10 Jean-Philippe Lang
You can now access project1 repository using this url:
234 1 Jean-Philippe Lang
235 1 Jean-Philippe Lang
  svn+ssh://svnhost/project1
236 1 Jean-Philippe Lang
237 15 Nicolas Chuche
h2. What if you want to allow Redmine to browse private repository ?
238 15 Nicolas Chuche
239 15 Nicolas Chuche
The previous recipes allow you to create repository on the fly and anonymous browsing. But, if your project is private or if the project isn't on the same server, you won't be able to browse it in Redmine.
240 15 Nicolas Chuche
241 15 Nicolas Chuche
h3. Redmine and svn are on the same server
242 15 Nicolas Chuche
243 15 Nicolas Chuche
In this case, you just need to use the @--url@ option like in the previous item to register the repository and the @--owner@ argument to set the repository owner to the mongrel/apache user so that it can access the repositories.
244 15 Nicolas Chuche
245 15 Nicolas Chuche
<pre>
246 15 Nicolas Chuche
ruby ./reposman.rb --redmine-host localhost:3000 --svn-dir /var/svn \
247 15 Nicolas Chuche
                   --url file:///var/svn/ --owner MONGREL_USER
248 15 Nicolas Chuche
</pre>
249 15 Nicolas Chuche
250 15 Nicolas Chuche
BUT, you won't be able to separate svn and Redmine hosts in the future (in fact you will be able to but you would have to manually update the repositories urls in the database and that's bad). A better way to do this, if you think you will need to separate those two servers one day, is to do like you already have two servers. To do this, read the next recipe.
251 15 Nicolas Chuche
252 15 Nicolas Chuche
h3. Redmine and svn aren't on the same server
253 15 Nicolas Chuche
254 15 Nicolas Chuche
There's more than one way to do this, one could be to use a specific user to browse the repository with svnserve or svn+ssh but I don't like this way (don't ask why). Another way is to add a third access way (we already have svn+ssh for registered users and svnserve for anonymous users).
255 15 Nicolas Chuche
256 15 Nicolas Chuche
In the following, the Redmine server is known as redmine.my.domain and the svn as svn.my.domain. You need to have apache/apache2 and mod_dav_svn on the svn server.
257 15 Nicolas Chuche
258 15 Nicolas Chuche
1. configure your apache to serve the svn repository just for the Redmine server
259 15 Nicolas Chuche
260 15 Nicolas Chuche
Just add something like that in your @apache.conf@ or in a file in the directory @/etc/apache/conf.d@:
261 15 Nicolas Chuche
262 15 Nicolas Chuche
<pre>
263 15 Nicolas Chuche
   LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so
264 15 Nicolas Chuche
   <Location /svn>
265 15 Nicolas Chuche
   DAV svn
266 15 Nicolas Chuche
   # this must be the path you give to reposman with -s,--svn-dir argument
267 15 Nicolas Chuche
   SVNParentPath "/var/svn"
268 15 Nicolas Chuche
   Order allow,deny
269 15 Nicolas Chuche
   Allow from ip.of.my.redmine.server
270 15 Nicolas Chuche
   </Location>
271 15 Nicolas Chuche
</pre>
272 15 Nicolas Chuche
273 15 Nicolas Chuche
Verify you can access it from your Redmine server.
274 15 Nicolas Chuche
275 15 Nicolas Chuche
2. change your reposman cron by adding the @--owner@ argument with the apache user :
276 15 Nicolas Chuche
277 15 Nicolas Chuche
<pre>
278 15 Nicolas Chuche
ruby ./reposman.rb --redmine-host http://redmine.my.domain/ --svn-dir /var/svn
279 15 Nicolas Chuche
                   --url http://svn.my.domain/svn/ --owner APACHE_USER
280 15 Nicolas Chuche
</pre>
281 15 Nicolas Chuche
282 15 Nicolas Chuche
h2. Web Service and Security
283 15 Nicolas Chuche
284 15 Nicolas Chuche
For the moment, the WS is open to everybody once actived and you surely don't want that someone register project for you. You can block access to the WS with apache/mongrel (if you don't use apache, I let you do your homework...) with the Location apache directive like this :
285 15 Nicolas Chuche
286 15 Nicolas Chuche
<pre>
287 15 Nicolas Chuche
<VirtualHost *:80>
288 15 Nicolas Chuche
   ServerName redmine.my.domain
289 15 Nicolas Chuche
   ServerAdmin webmaster@localhost
290 15 Nicolas Chuche
291 15 Nicolas Chuche
   <Location /sys>
292 15 Nicolas Chuche
      Order allow,deny
293 15 Nicolas Chuche
      Allow from ip.of.my.svn.server
294 15 Nicolas Chuche
   </Location>
295 15 Nicolas Chuche
296 15 Nicolas Chuche
   ProxyPass / http://localhost:3000/
297 15 Nicolas Chuche
   ProxyPassReverse / http://localhost:3000/
298 15 Nicolas Chuche
</VirtualHost>
299 15 Nicolas Chuche
</pre>
300 5 Jean-Philippe Lang
301 16 Jean-Philippe Lang
fn1. Other databases can not be used because of various problems: no pam module, no sha1 handling,...