4083 lines
305 KiB
HTML
4083 lines
305 KiB
HTML
|
<!DOCTYPE html><html lang="fr">
|
|||
|
<head><meta charset="utf-8">
|
|||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>OVH vps506197 Debian 10 - yunohost (wireguard, audio navidrome et static) -cinay.eu - YannStatic</title>
|
|||
|
|
|||
|
<meta name="description" content="">
|
|||
|
<link rel="canonical" href="https://static.rnmkcy.eu/2020/11/04/vps506197_Debian_10_yunohost-cinay.eu.html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
|
|||
|
|
|||
|
<!-- - include head/favicon.html - -->
|
|||
|
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
|
|||
|
<!-- end custom head snippets --><script>(function() {
|
|||
|
window.isArray = function(val) {
|
|||
|
return Object.prototype.toString.call(val) === '[object Array]';
|
|||
|
};
|
|||
|
window.isString = function(val) {
|
|||
|
return typeof val === 'string';
|
|||
|
};
|
|||
|
|
|||
|
window.hasEvent = function(event) {
|
|||
|
return 'on'.concat(event) in window.document;
|
|||
|
};
|
|||
|
|
|||
|
window.isOverallScroller = function(node) {
|
|||
|
return node === document.documentElement || node === document.body || node === window;
|
|||
|
};
|
|||
|
|
|||
|
window.isFormElement = function(node) {
|
|||
|
var tagName = node.tagName;
|
|||
|
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
|
|||
|
};
|
|||
|
|
|||
|
window.pageLoad = (function () {
|
|||
|
var loaded = false, cbs = [];
|
|||
|
window.addEventListener('load', function () {
|
|||
|
var i;
|
|||
|
loaded = true;
|
|||
|
if (cbs.length > 0) {
|
|||
|
for (i = 0; i < cbs.length; i++) {
|
|||
|
cbs[i]();
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
return {
|
|||
|
then: function(cb) {
|
|||
|
cb && (loaded ? cb() : (cbs.push(cb)));
|
|||
|
}
|
|||
|
};
|
|||
|
})();
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
window.throttle = function(func, wait) {
|
|||
|
var args, result, thisArg, timeoutId, lastCalled = 0;
|
|||
|
|
|||
|
function trailingCall() {
|
|||
|
lastCalled = new Date;
|
|||
|
timeoutId = null;
|
|||
|
result = func.apply(thisArg, args);
|
|||
|
}
|
|||
|
return function() {
|
|||
|
var now = new Date,
|
|||
|
remaining = wait - (now - lastCalled);
|
|||
|
|
|||
|
args = arguments;
|
|||
|
thisArg = this;
|
|||
|
|
|||
|
if (remaining <= 0) {
|
|||
|
clearTimeout(timeoutId);
|
|||
|
timeoutId = null;
|
|||
|
lastCalled = now;
|
|||
|
result = func.apply(thisArg, args);
|
|||
|
} else if (!timeoutId) {
|
|||
|
timeoutId = setTimeout(trailingCall, remaining);
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
};
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var Set = (function() {
|
|||
|
var add = function(item) {
|
|||
|
var i, data = this._data;
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
if (data[i] === item) {
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
this.size ++;
|
|||
|
data.push(item);
|
|||
|
return data;
|
|||
|
};
|
|||
|
|
|||
|
var Set = function(data) {
|
|||
|
this.size = 0;
|
|||
|
this._data = [];
|
|||
|
var i;
|
|||
|
if (data.length > 0) {
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
add.call(this, data[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
Set.prototype.add = add;
|
|||
|
Set.prototype.get = function(index) { return this._data[index]; };
|
|||
|
Set.prototype.has = function(item) {
|
|||
|
var i, data = this._data;
|
|||
|
for (i = 0; i < data.length; i++) {
|
|||
|
if (this.get(i) === item) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
Set.prototype.is = function(map) {
|
|||
|
if (map._data.length !== this._data.length) { return false; }
|
|||
|
var i, j, flag, tData = this._data, mData = map._data;
|
|||
|
for (i = 0; i < tData.length; i++) {
|
|||
|
for (flag = false, j = 0; j < mData.length; j++) {
|
|||
|
if (tData[i] === mData[j]) {
|
|||
|
flag = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!flag) { return false; }
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
Set.prototype.values = function() {
|
|||
|
return this._data;
|
|||
|
};
|
|||
|
return Set;
|
|||
|
})();
|
|||
|
|
|||
|
window.Lazyload = (function(doc) {
|
|||
|
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
|
|||
|
var createNode = function(name, attrs) {
|
|||
|
var node = doc.createElement(name), attr;
|
|||
|
for (attr in attrs) {
|
|||
|
if (attrs.hasOwnProperty(attr)) {
|
|||
|
node.setAttribute(attr, attrs[attr]);
|
|||
|
}
|
|||
|
}
|
|||
|
return node;
|
|||
|
};
|
|||
|
var end = function(type, url) {
|
|||
|
var s, q, qi, cbs, i, j, cur, val, flag;
|
|||
|
if (type === 'js' || type ==='css') {
|
|||
|
s = sources[type], q = queue[type];
|
|||
|
s[url] = true;
|
|||
|
for (i = 0; i < q.length; i++) {
|
|||
|
cur = q[i];
|
|||
|
if (cur.urls.has(url)) {
|
|||
|
qi = cur, val = qi.urls.values();
|
|||
|
qi && (cbs = qi.callbacks);
|
|||
|
for (flag = true, j = 0; j < val.length; j++) {
|
|||
|
cur = val[j];
|
|||
|
if (!s[cur]) {
|
|||
|
flag = false;
|
|||
|
}
|
|||
|
}
|
|||
|
if (flag && cbs && cbs.length > 0) {
|
|||
|
for (j = 0; j < cbs.length; j++) {
|
|||
|
cbs[j].call(context);
|
|||
|
}
|
|||
|
qi.load = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
var load = function(type, urls, callback) {
|
|||
|
var s, q, qi, node, i, cur,
|
|||
|
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
|
|||
|
if (type === 'js' || type ==='css') {
|
|||
|
s = sources[type], q = queue[type];
|
|||
|
for (i = 0; i < q.length; i++) {
|
|||
|
cur = q[i];
|
|||
|
if (_urls.is(cur.urls)) {
|
|||
|
qi = cur;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
val = _urls.values();
|
|||
|
if (qi) {
|
|||
|
callback && (qi.load || qi.callbacks.push(callback));
|
|||
|
callback && (qi.load && callback());
|
|||
|
} else {
|
|||
|
q.push({
|
|||
|
urls: _urls,
|
|||
|
callbacks: callback ? [callback] : [],
|
|||
|
load: false
|
|||
|
});
|
|||
|
for (i = 0; i < val.length; i++) {
|
|||
|
node = null, url = val[i];
|
|||
|
if (s[url] === undefined) {
|
|||
|
(type === 'js' ) && (node = createNode('script', { src: url }));
|
|||
|
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
|
|||
|
if (node) {
|
|||
|
node.onload = (function(type, url) {
|
|||
|
return function() {
|
|||
|
end(type, url);
|
|||
|
};
|
|||
|
})(type, url);
|
|||
|
(doc.head || doc.body).appendChild(node);
|
|||
|
s[url] = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
return {
|
|||
|
js: function(url, callback) {
|
|||
|
load('js', url, callback);
|
|||
|
},
|
|||
|
css: function(url, callback) {
|
|||
|
load('css', url, callback);
|
|||
|
}
|
|||
|
};
|
|||
|
})(this.document);
|
|||
|
})();
|
|||
|
</script><script>
|
|||
|
(function() {
|
|||
|
var TEXT_VARIABLES = {
|
|||
|
version: '2.2.6',
|
|||
|
sources: {
|
|||
|
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
|
|||
|
jquery: '/assets/js/jquery.min.js',
|
|||
|
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
|
|||
|
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
|
|||
|
gitalk: {
|
|||
|
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
|
|||
|
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
|
|||
|
},
|
|||
|
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
|
|||
|
},
|
|||
|
site: {
|
|||
|
toc: {
|
|||
|
selectors: 'h1,h2,h3'
|
|||
|
}
|
|||
|
},
|
|||
|
paths: {
|
|||
|
search_js: '/assets/search.js'
|
|||
|
}
|
|||
|
};
|
|||
|
window.TEXT_VARIABLES = TEXT_VARIABLES;
|
|||
|
})();
|
|||
|
</script>
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<div class="root" data-is-touch="false">
|
|||
|
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
|
|||
|
|
|||
|
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
|
|||
|
<div class="header__title">
|
|||
|
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
|
|||
|
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
|
|||
|
<!-- Champ de recherche -->
|
|||
|
<div id="searchbox" class="search search--dark" style="visibility: visible">
|
|||
|
<div class="main">
|
|||
|
<div class="search__header"></div>
|
|||
|
<div class="search-bar">
|
|||
|
<div class="search-box js-search-box">
|
|||
|
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
|||
|
<input id="search-input" type="text" />
|
|||
|
<!-- <div class="search-box__icon-clear js-icon-clear">
|
|||
|
<a><i class="fas fa-times"></i></a>
|
|||
|
</div> -->
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<!-- Script pointing to search-script.js -->
|
|||
|
<script>/*!
|
|||
|
* Simple-Jekyll-Search
|
|||
|
* Copyright 2015-2020, Christian Fei
|
|||
|
* Licensed under the MIT License.
|
|||
|
*/
|
|||
|
|
|||
|
(function(){
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Templater_7 = {
|
|||
|
compile: compile,
|
|||
|
setOptions: setOptions
|
|||
|
}
|
|||
|
|
|||
|
const options = {}
|
|||
|
options.pattern = /\{(.*?)\}/g
|
|||
|
options.template = ''
|
|||
|
options.middleware = function () {}
|
|||
|
|
|||
|
function setOptions (_options) {
|
|||
|
options.pattern = _options.pattern || options.pattern
|
|||
|
options.template = _options.template || options.template
|
|||
|
if (typeof _options.middleware === 'function') {
|
|||
|
options.middleware = _options.middleware
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function compile (data) {
|
|||
|
return options.template.replace(options.pattern, function (match, prop) {
|
|||
|
const value = options.middleware(prop, data[prop], options.template)
|
|||
|
if (typeof value !== 'undefined') {
|
|||
|
return value
|
|||
|
}
|
|||
|
return data[prop] || match
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
'use strict';
|
|||
|
|
|||
|
function fuzzysearch (needle, haystack) {
|
|||
|
var tlen = haystack.length;
|
|||
|
var qlen = needle.length;
|
|||
|
if (qlen > tlen) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (qlen === tlen) {
|
|||
|
return needle === haystack;
|
|||
|
}
|
|||
|
outer: for (var i = 0, j = 0; i < qlen; i++) {
|
|||
|
var nch = needle.charCodeAt(i);
|
|||
|
while (j < tlen) {
|
|||
|
if (haystack.charCodeAt(j++) === nch) {
|
|||
|
continue outer;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var _$fuzzysearch_1 = fuzzysearch;
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
|
|||
|
|
|||
|
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
|
|||
|
|
|||
|
function FuzzySearchStrategy () {
|
|||
|
this.matches = function (string, crit) {
|
|||
|
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
|
|||
|
|
|||
|
function LiteralSearchStrategy () {
|
|||
|
this.matches = function (str, crit) {
|
|||
|
if (!str) return false
|
|||
|
|
|||
|
str = str.trim().toLowerCase()
|
|||
|
crit = crit.trim().toLowerCase()
|
|||
|
|
|||
|
return crit.split(' ').filter(function (word) {
|
|||
|
return str.indexOf(word) >= 0
|
|||
|
}).length === crit.split(' ').length
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Repository_4 = {
|
|||
|
put: put,
|
|||
|
clear: clear,
|
|||
|
search: search,
|
|||
|
setOptions: __setOptions_4
|
|||
|
}
|
|||
|
|
|||
|
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
|
|||
|
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
|
|||
|
|
|||
|
function NoSort () {
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
const data = []
|
|||
|
let opt = {}
|
|||
|
|
|||
|
opt.fuzzy = false
|
|||
|
opt.limit = 10
|
|||
|
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = NoSort
|
|||
|
opt.exclude = []
|
|||
|
|
|||
|
function put (data) {
|
|||
|
if (isObject(data)) {
|
|||
|
return addObject(data)
|
|||
|
}
|
|||
|
if (isArray(data)) {
|
|||
|
return addArray(data)
|
|||
|
}
|
|||
|
return undefined
|
|||
|
}
|
|||
|
function clear () {
|
|||
|
data.length = 0
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function isObject (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
|
|||
|
}
|
|||
|
|
|||
|
function isArray (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
|
|||
|
}
|
|||
|
|
|||
|
function addObject (_data) {
|
|||
|
data.push(_data)
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function addArray (_data) {
|
|||
|
const added = []
|
|||
|
clear()
|
|||
|
for (let i = 0, len = _data.length; i < len; i++) {
|
|||
|
if (isObject(_data[i])) {
|
|||
|
added.push(addObject(_data[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
return added
|
|||
|
}
|
|||
|
|
|||
|
function search (crit) {
|
|||
|
if (!crit) {
|
|||
|
return []
|
|||
|
}
|
|||
|
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
|
|||
|
}
|
|||
|
|
|||
|
function __setOptions_4 (_opt) {
|
|||
|
opt = _opt || {}
|
|||
|
|
|||
|
opt.fuzzy = _opt.fuzzy || false
|
|||
|
opt.limit = _opt.limit || 10
|
|||
|
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = _opt.sort || NoSort
|
|||
|
opt.exclude = _opt.exclude || []
|
|||
|
}
|
|||
|
|
|||
|
function findMatches (data, crit, strategy, opt) {
|
|||
|
const matches = []
|
|||
|
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
|
|||
|
const match = findMatchesInObject(data[i], crit, strategy, opt)
|
|||
|
if (match) {
|
|||
|
matches.push(match)
|
|||
|
}
|
|||
|
}
|
|||
|
return matches
|
|||
|
}
|
|||
|
|
|||
|
function findMatchesInObject (obj, crit, strategy, opt) {
|
|||
|
for (const key in obj) {
|
|||
|
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
|
|||
|
return obj
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isExcluded (term, excludedTerms) {
|
|||
|
for (let i = 0, len = excludedTerms.length; i < len; i++) {
|
|||
|
const excludedTerm = excludedTerms[i]
|
|||
|
if (new RegExp(excludedTerm).test(term)) {
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
/* globals ActiveXObject:false */
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$JSONLoader_2 = {
|
|||
|
load: load
|
|||
|
}
|
|||
|
|
|||
|
function load (location, callback) {
|
|||
|
const xhr = getXHR()
|
|||
|
xhr.open('GET', location, true)
|
|||
|
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
|
|||
|
xhr.send()
|
|||
|
}
|
|||
|
|
|||
|
function createStateChangeListener (xhr, callback) {
|
|||
|
return function () {
|
|||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|||
|
try {
|
|||
|
callback(null, JSON.parse(xhr.responseText))
|
|||
|
} catch (err) {
|
|||
|
callback(err, null)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getXHR () {
|
|||
|
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$OptionsValidator_3 = function OptionsValidator (params) {
|
|||
|
if (!validateParams(params)) {
|
|||
|
throw new Error('-- OptionsValidator: required options missing')
|
|||
|
}
|
|||
|
|
|||
|
if (!(this instanceof OptionsValidator)) {
|
|||
|
return new OptionsValidator(params)
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = params.required
|
|||
|
|
|||
|
this.getRequiredOptions = function () {
|
|||
|
return requiredOptions
|
|||
|
}
|
|||
|
|
|||
|
this.validate = function (parameters) {
|
|||
|
const errors = []
|
|||
|
requiredOptions.forEach(function (requiredOptionName) {
|
|||
|
if (typeof parameters[requiredOptionName] === 'undefined') {
|
|||
|
errors.push(requiredOptionName)
|
|||
|
}
|
|||
|
})
|
|||
|
return errors
|
|||
|
}
|
|||
|
|
|||
|
function validateParams (params) {
|
|||
|
if (!params) {
|
|||
|
return false
|
|||
|
}
|
|||
|
return typeof params.required !== 'undefined' && params.required instanceof Array
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$utils_9 = {
|
|||
|
merge: merge,
|
|||
|
isJSON: isJSON
|
|||
|
}
|
|||
|
|
|||
|
function merge (defaultParams, mergeParams) {
|
|||
|
const mergedOptions = {}
|
|||
|
for (const option in defaultParams) {
|
|||
|
mergedOptions[option] = defaultParams[option]
|
|||
|
if (typeof mergeParams[option] !== 'undefined') {
|
|||
|
mergedOptions[option] = mergeParams[option]
|
|||
|
}
|
|||
|
}
|
|||
|
return mergedOptions
|
|||
|
}
|
|||
|
|
|||
|
function isJSON (json) {
|
|||
|
try {
|
|||
|
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
|
|||
|
return true
|
|||
|
}
|
|||
|
return false
|
|||
|
} catch (err) {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var _$src_8 = {};
|
|||
|
(function (window) {
|
|||
|
'use strict'
|
|||
|
|
|||
|
let options = {
|
|||
|
searchInput: null,
|
|||
|
resultsContainer: null,
|
|||
|
json: [],
|
|||
|
success: Function.prototype,
|
|||
|
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
|
|||
|
templateMiddleware: Function.prototype,
|
|||
|
sortMiddleware: function () {
|
|||
|
return 0
|
|||
|
},
|
|||
|
noResultsText: 'No results found',
|
|||
|
limit: 10,
|
|||
|
fuzzy: false,
|
|||
|
debounceTime: null,
|
|||
|
exclude: []
|
|||
|
}
|
|||
|
|
|||
|
let debounceTimerHandle
|
|||
|
const debounce = function (func, delayMillis) {
|
|||
|
if (delayMillis) {
|
|||
|
clearTimeout(debounceTimerHandle)
|
|||
|
debounceTimerHandle = setTimeout(func, delayMillis)
|
|||
|
} else {
|
|||
|
func.call()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
|
|||
|
|
|||
|
/* removed: const _$Templater_7 = require('./Templater') */;
|
|||
|
/* removed: const _$Repository_4 = require('./Repository') */;
|
|||
|
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
|
|||
|
const optionsValidator = _$OptionsValidator_3({
|
|||
|
required: requiredOptions
|
|||
|
})
|
|||
|
/* removed: const _$utils_9 = require('./utils') */;
|
|||
|
|
|||
|
window.SimpleJekyllSearch = function (_options) {
|
|||
|
const errors = optionsValidator.validate(_options)
|
|||
|
if (errors.length > 0) {
|
|||
|
throwError('You must specify the following required options: ' + requiredOptions)
|
|||
|
}
|
|||
|
|
|||
|
options = _$utils_9.merge(options, _options)
|
|||
|
|
|||
|
_$Templater_7.setOptions({
|
|||
|
template: options.searchResultTemplate,
|
|||
|
middleware: options.templateMiddleware
|
|||
|
})
|
|||
|
|
|||
|
_$Repository_4.setOptions({
|
|||
|
fuzzy: options.fuzzy,
|
|||
|
limit: options.limit,
|
|||
|
sort: options.sortMiddleware,
|
|||
|
exclude: options.exclude
|
|||
|
})
|
|||
|
|
|||
|
if (_$utils_9.isJSON(options.json)) {
|
|||
|
initWithJSON(options.json)
|
|||
|
} else {
|
|||
|
initWithURL(options.json)
|
|||
|
}
|
|||
|
|
|||
|
const rv = {
|
|||
|
search: search
|
|||
|
}
|
|||
|
|
|||
|
typeof options.success === 'function' && options.success.call(rv)
|
|||
|
return rv
|
|||
|
}
|
|||
|
|
|||
|
function initWithJSON (json) {
|
|||
|
_$Repository_4.put(json)
|
|||
|
registerInput()
|
|||
|
}
|
|||
|
|
|||
|
function initWithURL (url) {
|
|||
|
_$JSONLoader_2.load(url, function (err, json) {
|
|||
|
if (err) {
|
|||
|
throwError('failed to get JSON (' + url + ')')
|
|||
|
}
|
|||
|
initWithJSON(json)
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function emptyResultsContainer () {
|
|||
|
options.resultsContainer.innerHTML = ''
|
|||
|
}
|
|||
|
|
|||
|
function appendToResultsContainer (text) {
|
|||
|
options.resultsContainer.innerHTML += text
|
|||
|
}
|
|||
|
|
|||
|
function registerInput () {
|
|||
|
options.searchInput.addEventListener('input', function (e) {
|
|||
|
if (isWhitelistedKey(e.which)) {
|
|||
|
emptyResultsContainer()
|
|||
|
debounce(function () { search(e.target.value) }, options.debounceTime)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function search (query) {
|
|||
|
if (isValidQuery(query)) {
|
|||
|
emptyResultsContainer()
|
|||
|
render(_$Repository_4.search(query), query)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function render (results, query) {
|
|||
|
const len = results.length
|
|||
|
if (len === 0) {
|
|||
|
return appendToResultsContainer(options.noResultsText)
|
|||
|
}
|
|||
|
for (let i = 0; i < len; i++) {
|
|||
|
results[i].query = query
|
|||
|
appendToResultsContainer(_$Templater_7.compile(results[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isValidQuery (query) {
|
|||
|
return query && query.length > 0
|
|||
|
}
|
|||
|
|
|||
|
function isWhitelistedKey (key) {
|
|||
|
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
|
|||
|
}
|
|||
|
|
|||
|
function throwError (message) {
|
|||
|
throw new Error('SimpleJekyllSearch --- ' + message)
|
|||
|
}
|
|||
|
})(window)
|
|||
|
|
|||
|
}());
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- Configuration -->
|
|||
|
<script>
|
|||
|
SimpleJekyllSearch({
|
|||
|
searchInput: document.getElementById('search-input'),
|
|||
|
resultsContainer: document.getElementById('results-container'),
|
|||
|
json: '/search.json',
|
|||
|
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date} {title}</a></li>'
|
|||
|
searchResultTemplate: '<li><a href="{url}">{date} {title}</a></li>'
|
|||
|
})
|
|||
|
</script>
|
|||
|
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
|
|||
|
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/aide-jekyll-text-theme.html">Aide</a></li></ul>
|
|||
|
</nav></div>
|
|||
|
</header>
|
|||
|
|
|||
|
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
|
|||
|
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
|
|||
|
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">OVH vps506197 Debian 10 - yunohost (wireguard, audio navidrome et static) -cinay.eu</h1></header></div><meta itemprop="headline" content="OVH vps506197 Debian 10 - yunohost (wireguard, audio navidrome et static) -cinay.eu"><div class="article__info clearfix"><ul class="left-col menu"><li>
|
|||
|
<a class="button button--secondary button--pill button--sm"
|
|||
|
href="/archive.html?tag=yunohost">yunohost</a>
|
|||
|
</li></ul><ul class="right-col menu"><li>
|
|||
|
<i class="far fa-calendar-alt"></i> <span title="Création" style="color:#FF00FF"> 4 nov. 2020</span></li></ul></div><meta itemprop="datePublished" content="2020-11-04T00:00:00+01:00">
|
|||
|
<meta itemprop="keywords" content="yunohost"><div class="js-article-content">
|
|||
|
<div class="layout--article"><!-- start custom article top snippet -->
|
|||
|
<style>
|
|||
|
#myBtn {
|
|||
|
display: none;
|
|||
|
position: fixed;
|
|||
|
bottom: 10px;
|
|||
|
right: 10px;
|
|||
|
z-index: 99;
|
|||
|
font-size: 12px;
|
|||
|
font-weight: bold;
|
|||
|
border: none;
|
|||
|
outline: none;
|
|||
|
background-color: white;
|
|||
|
color: black;
|
|||
|
cursor: pointer;
|
|||
|
padding: 5px;
|
|||
|
border-radius: 4px;
|
|||
|
}
|
|||
|
|
|||
|
#myBtn:hover {
|
|||
|
background-color: #555;
|
|||
|
}
|
|||
|
</style>
|
|||
|
|
|||
|
<button onclick="topFunction()" id="myBtn" title="Haut de page">⇧</button>
|
|||
|
|
|||
|
<script>
|
|||
|
//Get the button
|
|||
|
var mybutton = document.getElementById("myBtn");
|
|||
|
|
|||
|
// When the user scrolls down 20px from the top of the document, show the button
|
|||
|
window.onscroll = function() {scrollFunction()};
|
|||
|
|
|||
|
function scrollFunction() {
|
|||
|
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
|
|||
|
mybutton.style.display = "block";
|
|||
|
} else {
|
|||
|
mybutton.style.display = "none";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// When the user clicks on the button, scroll to the top of the document
|
|||
|
function topFunction() {
|
|||
|
document.body.scrollTop = 0;
|
|||
|
document.documentElement.scrollTop = 0;
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
|
|||
|
<!-- end custom article top snippet -->
|
|||
|
<div class="article__content" itemprop="articleBody"><details>
|
|||
|
<summary><b>Afficher/cacher Sommaire</b></summary>
|
|||
|
<!-- affichage sommaire -->
|
|||
|
<div class="toc-aside js-toc-root"></div>
|
|||
|
</details><p><img src="/images/yunohost.png" alt="" width="60" /></p>
|
|||
|
|
|||
|
<p><em>OVH KVM OpenStack vps506197 (1 vCore 2.4Ghz/4Go Ram/20Go SSD/Local Raid10/Strasbourg)</em></p>
|
|||
|
|
|||
|
<h2 id="noyau-réseau-et-domaine">Noyau, réseau et domaine</h2>
|
|||
|
|
|||
|
<p><img src="/images/OVH-320px-Logo.png" alt="OVH" width="70" /></p>
|
|||
|
|
|||
|
<p>Debian Buster<br />
|
|||
|
PARAMETRES D’ACCES:<br />
|
|||
|
L’adresse IPv4 du VPS est : 164.132.104.145<br />
|
|||
|
L’adresse IPv6 du VPS est : 2001:41d0:0401:3200::06e7</p>
|
|||
|
|
|||
|
<p>Le nom du VPS est : vps506197.ovh.net<br />
|
|||
|
Connexion SSH en “root” ( H2eHmVmw )</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@164.132.104.145
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="installer-noyau-56">Installer noyau 5.6+</h4>
|
|||
|
|
|||
|
<p><em>Le noyau 5.6 a le module wireguard intégré</em></p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"deb http://deb.debian.org/debian/ unstable main"</span> | <span class="nb">sudo tee</span> /etc/apt/sources.list.d/unstable-wireguard.list
|
|||
|
<span class="nb">printf</span> <span class="s1">'Package: *\nPin: release a=unstable\nPin-Priority: 90\n'</span> | <span class="nb">sudo tee</span> /etc/apt/preferences.d/limit-unstable
|
|||
|
apt update <span class="o">&&</span> apt upgrade
|
|||
|
apt <span class="nb">install </span>linux-image-5.6.0-2-cloud-amd64
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="réseau">Réseau</h4>
|
|||
|
|
|||
|
<p>Créer un bash pour désactiver l’initialisation réseau par le cloud sur le VPS OVH</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano initres.sh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
|
|||
|
<span class="c">#</span>
|
|||
|
<span class="c"># To disable cloud-init's network configuration capabilities, write a file</span>
|
|||
|
<span class="c"># /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:</span>
|
|||
|
<span class="c"># network: {config: disabled}</span>
|
|||
|
<span class="c">#</span>
|
|||
|
<span class="c">#Création du fichier **/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg** en mode su</span>
|
|||
|
<span class="nb">echo</span> <span class="s2">"network: {config: disabled}"</span> <span class="o">></span> /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
|
|||
|
<span class="c">#</span>
|
|||
|
<span class="c"># Effacerle fichier /etc/network/interfaces </span>
|
|||
|
<span class="nb">rm</span> /etc/network/interfaces
|
|||
|
<span class="c"># Recréer le fichier /etc/network/interfaces</span>
|
|||
|
<span class="nb">cat</span> <span class="o">></span> /etc/network/interfaces <span class="o"><<</span> <span class="no">EOF</span><span class="sh">
|
|||
|
auto lo
|
|||
|
iface lo inet loopback
|
|||
|
|
|||
|
auto eth0
|
|||
|
iface eth0 inet dhcp
|
|||
|
iface eth0 inet6 static
|
|||
|
address 2001:41d0:0401:3200::06e7
|
|||
|
netmask 128
|
|||
|
post-up /sbin/ip -6 route add 2001:41d0:0401:3200::1 dev eth0
|
|||
|
post-up /sbin/ip -6 route add default via 2001:41d0:0401:3200::1 dev eth0
|
|||
|
pre-down /sbin/ip -6 route del default via 2001:41d0:0401:3200::1 dev eth0
|
|||
|
pre-down /sbin/ip -6 route del 2001:41d0:0401:3200::1 dev eth0
|
|||
|
</span><span class="no">EOF
|
|||
|
</span><span class="c">#</span>
|
|||
|
<span class="c"># Configuration OVH à modifier /etc/cloud/cloud.cfg </span>
|
|||
|
<span class="nb">sed</span> <span class="nt">-i</span> <span class="s1">'s/preserve_hostname: false/preserve_hostname: true/g'</span> /etc/cloud/cloud.cfg
|
|||
|
<span class="nb">sed</span> <span class="nt">-i</span> <span class="s1">'s/manage_etc_hosts: true/manage_etc_hosts: false/g'</span> /etc/cloud/cloud.cfg
|
|||
|
<span class="c">#</span>
|
|||
|
<span class="c"># Redémarrage de la machine</span>
|
|||
|
systemctl reboot
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Droits et exécution</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x initres.sh && ./initres.sh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Patienter quelques minutes avant la reconnexion…</p>
|
|||
|
|
|||
|
<p>Se connecter en root via SSH</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@164.132.104.145
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérifier le réseau <code class="language-plaintext highlighter-rouge">ip a</code> et noyau <code class="language-plaintext highlighter-rouge">uname -r</code></p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
|
|||
|
<span class="nb">link</span>/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
|||
|
inet 127.0.0.1/8 scope host lo
|
|||
|
valid_lft forever preferred_lft forever
|
|||
|
inet6 ::1/128 scope host
|
|||
|
valid_lft forever preferred_lft forever
|
|||
|
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
|
|||
|
<span class="nb">link</span>/ether fa:16:3e:f1:2a:30 brd ff:ff:ff:ff:ff:ff
|
|||
|
inet 164.132.104.145/32 brd 164.132.104.145 scope global dynamic eth0
|
|||
|
valid_lft 86295sec preferred_lft 86295sec
|
|||
|
inet6 2001:41d0:401:3200::6e7/128 scope global
|
|||
|
valid_lft forever preferred_lft forever
|
|||
|
inet6 fe80::f816:3eff:fef1:2a30/64 scope <span class="nb">link
|
|||
|
</span>valid_lft forever preferred_lft forever
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Noyau <strong>5.6.0-2-cloud-amd64</strong><br />
|
|||
|
Locales <strong>fr UTF8</strong> : <code class="language-plaintext highlighter-rouge">dpkg-reconfigure locales</code><br />
|
|||
|
Fuseau <strong>Europe/Paris</strong> : <code class="language-plaintext highlighter-rouge">dpkg-reconfigure tzdata</code></p>
|
|||
|
|
|||
|
<h4 id="domaine-cinayeu">domaine cinay.eu</h4>
|
|||
|
|
|||
|
<p><img src="/images/dns-logo.png" alt="dns" width="50" /></p>
|
|||
|
|
|||
|
<p>Zone dns OVH</p>
|
|||
|
|
|||
|
<p class="warning">Si vous utilisez des sous-domaines de type xxx.cinay.eu , vous devez renseigner chaque sous-domaine avec la directive <code class="language-plaintext highlighter-rouge">CNAME</code></p>
|
|||
|
|
|||
|
<p>Liste des sous-domaines (septembre 2020)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>div.cinay.eu
|
|||
|
gitea.cinay.eu
|
|||
|
static.cinay.eu
|
|||
|
wg.cinay.eu
|
|||
|
zic.cinay.eu
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$TTL</span> 3600
|
|||
|
@ IN SOA dns100.ovh.net. tech.ovh.net. <span class="o">(</span>2020102803 86400 3600 3600000 300<span class="o">)</span>
|
|||
|
IN NS ns100.ovh.net.
|
|||
|
IN NS dns100.ovh.net.
|
|||
|
IN MX 10 cinay.eu.
|
|||
|
IN A 164.132.104.145
|
|||
|
IN AAAA 2001:41d0:401:3200::6e7
|
|||
|
IN CAA 128 issue <span class="s2">"letsencrypt.org"</span>
|
|||
|
600 IN TXT <span class="s2">"v=spf1 a mx -all"</span>
|
|||
|
_dmarc IN TXT <span class="s2">"v=DMARC1;p=none;"</span>
|
|||
|
_xmpp-client._tcp IN SRV 0 5 5222 cinay.eu.
|
|||
|
_xmpp-server._tcp IN SRV 0 5 5269 cinay.eu.
|
|||
|
mail._domainkey IN TXT <span class="o">(</span> <span class="s2">"v=DKIM1;h=sha256;k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPZWCRYepm2ZXYhqkoJQSmKMBGrhKh08WVBfdMJD7mqKV3j8oNP1uLm9GVzVidFwyGnEntVrJJKajvHDwCQYFgWzA7y32VxYh74P0vEP6OzOjnCX0/57vp+Wjcxcc5pRAWCYFvUvIC55U0ows5zfdGYiA/ey8Toe68WOrd0YYubQIDAQAB;"</span> <span class="o">)</span>
|
|||
|
muc IN CNAME cinay.eu.
|
|||
|
pubsub IN CNAME cinay.eu.
|
|||
|
vjud IN CNAME cinay.eu.
|
|||
|
xmpp-upload IN CNAME cinay.eu.
|
|||
|
div IN CNAME cinay.eu.
|
|||
|
gitea IN CNAME cinay.eu.
|
|||
|
static IN CNAME cinay.eu.
|
|||
|
wg IN CNAME cinay.eu.
|
|||
|
zic IN CNAME cinay.eu.
|
|||
|
yanfi IN CNAME login.tutanota.com.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Reverse DNS sur “server” , IP 164.132.104.145 → cinay.eu<br />
|
|||
|
Reverse DNS sur “server” , 2001:41d0:401:3200::6e7 → cinay.eu</p>
|
|||
|
|
|||
|
<p>Test reverse DNS : <code class="language-plaintext highlighter-rouge">dig -x 164.132.104.145</code> et <code class="language-plaintext highlighter-rouge">dig -x 2001:41d0:401:3200:0:0:0:6e7</code></p>
|
|||
|
|
|||
|
<p>Hostname</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hostnamectl set-hostname cinay.eu
|
|||
|
hostnamectl
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Static <span class="nb">hostname</span>: cinay.eu
|
|||
|
Icon name: computer-vm
|
|||
|
Chassis: vm
|
|||
|
Machine ID: 0ef30511d74646618d92e464efb187ce
|
|||
|
Boot ID: 8c555dba579c417088eb060960c3c238
|
|||
|
Virtualization: kvm
|
|||
|
Operating System: Debian GNU/Linux 10 <span class="o">(</span>buster<span class="o">)</span>
|
|||
|
Kernel: Linux 5.6.0-2-cloud-amd64
|
|||
|
Architecture: x86-64
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="yunohost">Yunohost</h2>
|
|||
|
|
|||
|
<p><a href="https://forum.yunohost.org/t/alpha-stage-testing-for-yunohost-4-0-on-debian-buster-and-migration-shipped-in-yunohost-3-8-5/11766">Alpha-stage testing for YunoHost 4.0 on Debian Buster (and migration shipped in Yunohost 3.8.5)</a></p>
|
|||
|
|
|||
|
<p><img src="/images/yunohost.png" alt="yunohost" width="50" /></p>
|
|||
|
|
|||
|
<h3 id="installation">Installation</h3>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install curl
|
|||
|
curl https://raw.githubusercontent.com/YunoHost/install_script/buster-unstable/install_yunohost | bash
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Patienter…</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span> OK <span class="o">]</span> YunoHost installation completed <span class="o">!</span>
|
|||
|
<span class="o">===============================================================================</span>
|
|||
|
You should now proceed with Yunohost post-installation. This is where you will
|
|||
|
be asked <span class="k">for</span> :
|
|||
|
- the main domain of your server <span class="p">;</span>
|
|||
|
- the administration password.
|
|||
|
|
|||
|
You can perform this step :
|
|||
|
- from the <span class="nb">command </span>line, by running <span class="s1">'yunohost tools postinstall'</span> as root
|
|||
|
- or from your web browser, by accessing :
|
|||
|
- https://164.132.104.145/ <span class="o">(</span>global IP, <span class="k">if </span>you<span class="s1">'re on a VPS)
|
|||
|
|
|||
|
If this is your first time with YunoHost, it is strongly recommended to take
|
|||
|
time to read the administator documentation and in particular the sections
|
|||
|
'</span>Finalizing your setup<span class="s1">' and '</span>Getting to know YunoHost<span class="s1">'. It is available at
|
|||
|
the following URL : https://yunohost.org/admindoc
|
|||
|
===============================================================================
|
|||
|
</span></code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="post-installation">Post-installation</h3>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost tools postinstall
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Success! YunoHost is now configured
|
|||
|
Warning: The post-install completed! To finalize your setup, please consider:
|
|||
|
- adding a first user through the <span class="s1">'Users'</span> section of the webadmin <span class="o">(</span>or <span class="s1">'yunohost user create <username>'</span> <span class="k">in </span>command-line<span class="o">)</span><span class="p">;</span>
|
|||
|
- diagnose potential issues through the <span class="s1">'Diagnosis'</span> section of the webadmin <span class="o">(</span>or <span class="s1">'yunohost diagnosis run'</span> <span class="k">in </span>command-line<span class="o">)</span><span class="p">;</span>
|
|||
|
- reading the <span class="s1">'Finalizing your setup'</span> and <span class="s1">'Getting to know Yunohost'</span> parts <span class="k">in </span>the admin documentation: https://yunohost.org/admindoc.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="créer-un-utilisateur-yunohost">Créer un utilisateur (yunohost)</h3>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost user create yann
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>First name: yann
|
|||
|
Last name: cinayeu
|
|||
|
E-mail address: yann@cinay.eu
|
|||
|
You are now about to define a new user password. The password should be at least 8 characters long—though it is good practice to use a longer password <span class="o">(</span>i.e. a passphrase<span class="o">)</span> and/or to a variation of characters <span class="o">(</span>uppercase, lowercase, digits and special characters<span class="o">)</span><span class="nb">.</span>
|
|||
|
Password:
|
|||
|
Confirm password:
|
|||
|
Success! User created
|
|||
|
fullname: yann cinayeu
|
|||
|
mail: yann@cinay.eu
|
|||
|
username: yann
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="administration">Administration</h3>
|
|||
|
|
|||
|
<p><strong>Configuration DNS</strong></p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">;</span> Basic ipv4/ipv6 records
|
|||
|
@ 3600 IN A 164.132.104.145
|
|||
|
@ 3600 IN AAAA 2001:41d0:401:3200::6e7
|
|||
|
|
|||
|
<span class="p">;</span> XMPP
|
|||
|
_xmpp-client._tcp 3600 IN SRV 0 5 5222 cinay.eu.
|
|||
|
_xmpp-server._tcp 3600 IN SRV 0 5 5269 cinay.eu.
|
|||
|
muc 3600 IN CNAME @
|
|||
|
pubsub 3600 IN CNAME @
|
|||
|
vjud 3600 IN CNAME @
|
|||
|
xmpp-upload 3600 IN CNAME @
|
|||
|
|
|||
|
<span class="p">;</span> Mail
|
|||
|
@ 3600 IN MX 10 cinay.eu.
|
|||
|
@ 3600 IN TXT <span class="s2">"v=spf1 a mx -all"</span>
|
|||
|
mail._domainkey 3600 IN TXT <span class="s2">"v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPZWCRYepm2ZXYhqkoJQSmKMBGrhKh08WVBfdMJD7mqKV3j8oNP1uLm9GVzVidFwyGnEntVrJJKajvHDwCQYFgWzA7y32VxYh74P0vEP6OzOjnCX0/57vp+Wjcxcc5pRAWCYFvUvIC55U0ows5zfdGYiA/ey8Toe68WOrd0YYubQIDAQAB"</span>
|
|||
|
_dmarc 3600 IN TXT <span class="s2">"v=DMARC1; p=none"</span>
|
|||
|
|
|||
|
<span class="p">;</span> Extra
|
|||
|
<span class="k">*</span> 3600 IN A 164.132.104.145
|
|||
|
<span class="k">*</span> 3600 IN AAAA 2001:41d0:401:3200::6e7
|
|||
|
@ 3600 IN CAA 128 issue <span class="s2">"letsencrypt.org"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Certificats SSL</strong> <br />
|
|||
|
Installer un certificat Let’s Encrypt en ligne de commande</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain cert-install --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Info: Now attempting <span class="nb">install </span>of certificate <span class="k">for </span>domain cinay.eu!
|
|||
|
Success! Configuration updated <span class="k">for</span> <span class="s1">'dnsmasq'</span>
|
|||
|
Warning: No diagnosis cache yet <span class="k">for </span>category <span class="s1">'dnsrecords'</span>
|
|||
|
Warning: Subdomain <span class="s1">'xmpp-upload.cinay.eu'</span> does not resolve to the same IP address as <span class="s1">'cinay.eu'</span><span class="nb">.</span> Some features will not be available <span class="k">until </span>you fix this and regenerate the certificate.
|
|||
|
Info: Parsing account key...
|
|||
|
Info: Parsing CSR...
|
|||
|
Info: Found domains: cinay.eu
|
|||
|
Info: Getting directory...
|
|||
|
Info: Directory found!
|
|||
|
Info: Registering account...
|
|||
|
Info: Registered!
|
|||
|
Info: Creating new order...
|
|||
|
Info: Order created!
|
|||
|
Info: Verifying cinay.eu...
|
|||
|
Info: cinay.eu verified!
|
|||
|
Info: Signing certificate...
|
|||
|
Info: Certificate signed!
|
|||
|
Success! Configuration updated <span class="k">for</span> <span class="s1">'nginx'</span>
|
|||
|
Success! Let<span class="s1">'s Encrypt certificate now installed for the domain '</span>cinay.eu<span class="s1">'
|
|||
|
</span></code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="utilisateur-debian">Utilisateur “debian”</h3>
|
|||
|
|
|||
|
<p>Modifier le mot de passe de l’utilisateur existant <strong>debian</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>passwd debian
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Visudo pour les accès root via utilisateur <strong>debian</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "debian ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Changer le mot de passe root</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>passwd root
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="historique-de-la-ligne-de-commande">Historique de la ligne de commande</h3>
|
|||
|
|
|||
|
<p>Ajoutez la recherche d’historique de la ligne de commande au terminal.
|
|||
|
Tapez un début de commande précédent, puis utilisez shift + up (flèche haut) pour rechercher l’historique filtré avec le début de la commande.</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Global, tout utilisateur</span>
|
|||
|
<span class="nb">echo</span> <span class="s1">'"\e[1;2A": history-search-backward'</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/inputrc
|
|||
|
<span class="nb">echo</span> <span class="s1">'"\e[1;2B": history-search-forward'</span> | <span class="nb">sudo tee</span> <span class="nt">-a</span> /etc/inputrc
|
|||
|
<span class="nb">exit</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="openssh-clé-et-script">OpenSSH, clé et script</h3>
|
|||
|
|
|||
|
<p><img src="/images/ssh_logo1.png" alt="OpenSSH" width="100" /><br />
|
|||
|
<strong>connexion avec clé</strong><br />
|
|||
|
<u>sur l'ordinateur de bureau</u>
|
|||
|
Générer une paire de clé curve25519-sha256 (ECDH avec Curve25519 et SHA2) nommé <strong>kvm-cinay</strong> pour une liaison SSH avec le serveur KVM.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/kvm-vps506197
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Envoyer la clé publique sur le serveur KVM</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>scp ~/.ssh/kvm-vps506197.pub debian@164.132.104.145:/home/debian/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><u>sur le serveur KVM</u>
|
|||
|
On se connecte</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh debian@164.132.104.145
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Copier le contenu de la clé publique dans /home/$USER/.ssh/authorized_keys</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Sur le KVM ,créer un dossier .ssh</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir .ssh
|
|||
|
cat $HOME/kvm-vps506197.pub >> $HOME/.ssh/authorized_keys
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>et donner les droits</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod 600 $HOME/.ssh/authorized_keys
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>effacer le fichier de la clé</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rm $HOME/kvm-vps506197.pub
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier la configuration serveur SSH</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/ssh/sshd_config # attention aux 2 dernières lignes
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Port 55034
|
|||
|
PasswordAuthentication no <span class="c"># avant dernière ligne</span>
|
|||
|
PermitRootLogin no <span class="c"># dernière ligne</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><u>session SSH ne se termine pas correctement lors d'un "reboot" à distance</u><br />
|
|||
|
Si vous tentez de <strong>redémarrer/éteindre</strong> une machine distance par <strong>ssh</strong>, vous pourriez constater que votre session ne se termine pas correctement, vous laissant avec un terminal inactif jusqu’à l’expiration d’un long délai d’inactivité. Il existe un bogue 751636 à ce sujet. Pour l’instant, la solution de contournement à ce problème est d’installer :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install libpam-systemd # installé par défaut sur debian buster
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>cela terminera la session ssh avant que le réseau ne tombe.<br />
|
|||
|
Veuillez noter qu’il est nécessaire que PAM soit activé dans sshd.</p>
|
|||
|
|
|||
|
<p>Relancer openSSH</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart sshd
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ouvrir le port 55034 et fermer le port 22</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo yunohost firewall allow TCP 55034
|
|||
|
sudo yunohost firewall disallow TCP 22
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Accès depuis le poste distant avec la clé privée</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -p 55034 -i ~/.ssh/kvm-vps506197 debian@164.132.104.145
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="outils-scripts-motd-et-ssh_rc_bash">Outils, scripts motd et ssh_rc_bash</h3>
|
|||
|
|
|||
|
<p>Installer utilitaires</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install rsync curl tmux jq figlet git dnsutils tree -y
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Motd</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm /etc/motd && sudo nano /etc/motd
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ___ __ __ _ ___ ____
|
|||
|
__ __ _ __ ___| __| / <span class="se">\ </span> / / / |/ _ <span class="se">\|</span>__ |
|
|||
|
<span class="se">\ </span>V /| <span class="s1">'_ \(_-<|__ \| () |/ _ \| |\_, / / /
|
|||
|
\_/ | .__//__/|___/ \__/ \___/|_| /_/ /_/
|
|||
|
|_|
|
|||
|
__ (_) _ _ __ _ _ _ ___ _ _
|
|||
|
/ _|| || '</span> <span class="se">\ </span>/ _<span class="sb">`</span> <span class="o">||</span> <span class="o">||</span> | _ / <span class="nt">-_</span><span class="o">)</span>| <span class="o">||</span> |
|
|||
|
<span class="se">\_</span>_||_||_||_|<span class="se">\_</span>_,_| <span class="se">\_</span>, |<span class="o">(</span>_<span class="o">)</span><span class="se">\_</span>__| <span class="se">\_</span>,_|
|
|||
|
|__/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Script ssh_rc_bash</p>
|
|||
|
|
|||
|
<blockquote>
|
|||
|
<p>ATTENTION!!! Les scripts sur connexion peuvent poser des problèmes pour des appels externes autres que ssh</p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://static.xoyaz.xyz/files/ssh_rc_bash
|
|||
|
<span class="nb">chmod</span> +x ssh_rc_bash <span class="c"># rendre le bash exécutable</span>
|
|||
|
./ssh_rc_bash <span class="c"># exécution</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><img src="/images/vps506197.png" alt="" /></p>
|
|||
|
|
|||
|
<h3 id="domaine-yanfinet">Domaine yanfi.net</h3>
|
|||
|
|
|||
|
<p>DNS OVH yanfi.net géré par le serveur cinay.eu <br />
|
|||
|
Remplacer 51.75.120.106 → 164.132.104.145
|
|||
|
Remplacer 2001:41d0:305:2100::4dc0 → 2001:41d0:401:3200::6e7</p>
|
|||
|
|
|||
|
<p>Administration Yunohost → ajout domaine yanfi.net<br />
|
|||
|
Domaine yanfi.net <strong>Configuration DNS</strong> et ajuster le domaine yanfi.net sur OVH</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$TTL</span> 3600
|
|||
|
@ IN SOA dns110.ovh.net. tech.ovh.net. <span class="o">(</span>2020072800 86400 3600 3600000 300<span class="o">)</span>
|
|||
|
IN NS dns110.ovh.net.
|
|||
|
IN NS ns110.ovh.net.
|
|||
|
IN MX 10 yanfi.net.
|
|||
|
IN A 164.132.104.145
|
|||
|
IN AAAA 2001:41d0:401:3200::6e7
|
|||
|
IN CAA 128 issue <span class="s2">"letsencrypt.org"</span>
|
|||
|
600 IN TXT <span class="s2">"v=spf1 a mx -all"</span>
|
|||
|
<span class="k">*</span> IN CNAME yanfi.net.
|
|||
|
_dmarc IN TXT <span class="s2">"v=DMARC1; p=none"</span>
|
|||
|
_xmpp-client._tcp IN SRV 0 5 5222 yanfi.net.
|
|||
|
_xmpp-server._tcp IN SRV 0 5 5269 yanfi.net.
|
|||
|
mail._domainkey IN TXT <span class="o">(</span> <span class="s2">"v=DKIM1;h=sha256;k=rsa;p=MIGfMA0GQ.......IDAQAB;"</span> <span class="o">)</span>
|
|||
|
muc IN CNAME yanfi.net.
|
|||
|
pubsub IN CNAME yanfi.net.
|
|||
|
vjud IN CNAME yanfi.net.
|
|||
|
xmpp-upload IN CNAME yanfi.net.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Certificats en ligne de commande : <code class="language-plaintext highlighter-rouge">yunohost domain cert-install yanfi.net --no-checks</code></p>
|
|||
|
|
|||
|
<p>Paramétrage de la messagerie : <br />
|
|||
|
Thunderbird , il faut passer par les serveurs IMAP et SMTP cinay.eu<br />
|
|||
|
k-9mail android , il faut passer par les serveurs IMAP et SMTP yanfi.net</p>
|
|||
|
|
|||
|
<h2 id="go-node-python">Go Node Python</h2>
|
|||
|
|
|||
|
<h4 id="go">Go</h4>
|
|||
|
|
|||
|
<p><img src="/images/golang-color-icon2.png" alt="golang" width="50" /></p>
|
|||
|
|
|||
|
<p>Go installation (Debian) , installer la dernière version de Go (https://golang.org/dl/)</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~
|
|||
|
wget https://golang.org/dl/go1.15.3.linux-amd64.tar.gz
|
|||
|
<span class="nb">sudo tar</span> <span class="nt">-C</span> /usr/local <span class="nt">-xzf</span> go1.15.3.linux-amd64.tar.gz
|
|||
|
<span class="nb">rm </span>go1.15.3.linux-amd64.tar.gz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Environnement de configuration</p>
|
|||
|
|
|||
|
<p>Bash: <strong>~/.bashrc</strong></p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> <span class="nv">$HOME</span>/go
|
|||
|
<span class="nb">echo</span> <span class="s2">"export PATH=</span><span class="nv">$PATH</span><span class="s2">:/usr/local/go/bin:</span><span class="nv">$HOME</span><span class="s2">/go/bin"</span> <span class="o">>></span> ~/.bashrc
|
|||
|
<span class="nb">echo</span> <span class="s2">"export GOPATH=</span><span class="nv">$HOME</span><span class="s2">/go"</span> <span class="o">>></span> ~/.bashrc
|
|||
|
<span class="nb">source</span> ~/.bashrc
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="nodejs">Nodejs</h4>
|
|||
|
|
|||
|
<p><img src="/images/Node_logo.png" alt="nodejs" width="50" /></p>
|
|||
|
|
|||
|
<p>Installer la version LTS de nodejs pour le frontend.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install curl software-properties-common -y
|
|||
|
curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">## Run `sudo apt-get install -y nodejs` to install Node.js 14.x and npm</span>
|
|||
|
<span class="c">## You may also need development tools to build native addons:</span>
|
|||
|
<span class="nb">sudo </span>apt-get <span class="nb">install </span>gcc g++ make
|
|||
|
<span class="c">## To install the Yarn package manager, run:</span>
|
|||
|
curl <span class="nt">-sL</span> https://dl.yarnpkg.com/debian/pubkey.gpg | <span class="nb">sudo </span>apt-key add -
|
|||
|
<span class="nb">echo</span> <span class="s2">"deb https://dl.yarnpkg.com/debian/ stable main"</span> | <span class="nb">sudo tee</span> /etc/apt/sources.list.d/yarn.list
|
|||
|
<span class="nb">sudo </span>apt-get update <span class="o">&&</span> <span class="nb">sudo </span>apt-get <span class="nb">install </span>yarn
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Nodejs</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install -y nodejs
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="python-version-3-par-défaut">Python version 3 par défaut</h4>
|
|||
|
|
|||
|
<p><img src="/images/python-logo.png" alt="python" width="50" /></p>
|
|||
|
|
|||
|
<p>Pour changer la version de python à l’échelle du système, nous allons utiliser la commande update-alternatives en tant qu’utilisateur root.<br />
|
|||
|
Pour visualiser toutes les alternatives disponibles de python :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>update-alternatives --list python
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><em>update-alternatives: error: no alternatives for python</em></p>
|
|||
|
|
|||
|
<p>Le message d’erreur ci-dessus indique qu’aucune alternative de python n’a été reconnue par update-alternatives.<br />
|
|||
|
Pour cette raison, nous devons mettre à jour notre tableau des alternatives et inclure à la fois python2.7 et python3.7 :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><em>update-alternatives: using /usr/bin/python2.7 to provide /usr/bin/python (python) in auto mode</em></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>update-alternatives --install /usr/bin/python python /usr/bin/python3.7 2
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><em>update-alternatives: using /usr/bin/python3.7 to provide /usr/bin/python (python) in auto mode</em></p>
|
|||
|
|
|||
|
<p>L’option –install prend plusieurs arguments à partir desquels il sera capable de créer un lien symbolique. Le dernier argument spécifié défini la priorité, si aucune sélection manuelle alternative n’est donnée, l’option avec le numéro de priorité le plus élevé sera exécutée. Dans notre cas, nous avons défini une priorité 2 pour /usr/bin/python3.7 et de ce fait /usr/bin/python3.7 a été définie comme la version python par défaut par update-alternatives.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python --version
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><em>Python 3.7.3</em></p>
|
|||
|
|
|||
|
<p>Installer pip3</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install python3-pip
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="sshfs-partage-xoyazxyz">SSHFS partage xoyaz.xyz</h2>
|
|||
|
|
|||
|
<p><em>Secure shell file system (ou SSHFS) permet le partage d’un système de fichiers de manière sécurisée en utilisant le protocole SFTP de SSH</em></p>
|
|||
|
|
|||
|
<p>Le but, créer un accès réseau sur un autre serveur pour les gros volumes de fichiers (musique, livres, etc…)<br />
|
|||
|
Le dossier local <strong>/opt/sshfs/</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir -p /opt/sshfs
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Il faut créer une liaison réseau sécurisée entre <strong>cinay.eu ← → xoyaz.xyz</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install sshfs
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Autorisations</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Autorisations “utilisateur”
|
|||
|
<ul>
|
|||
|
<li>Exécuter <code class="language-plaintext highlighter-rouge">sshfs</code> (ou toute autre commande de montage FUSE) avec l’option <code class="language-plaintext highlighter-rouge">-o allow_other</code></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li>Autoriser l’accès “root” des supports <strong>fuse</strong>
|
|||
|
<ul>
|
|||
|
<li>Ajouter <code class="language-plaintext highlighter-rouge">user_allow_other</code> au fichier <strong>/etc/fuse.conf</strong></li>
|
|||
|
<li>Exécuter <code class="language-plaintext highlighter-rouge">sshfs</code> (ou toute autre commande de montage FUSE) avec l’option <code class="language-plaintext highlighter-rouge">-o allow_root</code></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<h4 id="partage-avec-serveur-xoyazxyz">Partage avec serveur xoyaz.xyz</h4>
|
|||
|
|
|||
|
<p>Clé privée <strong>OVZ-STORAGE-128</strong> pour accéder au serveur xoyaz.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod 600 /home/debian/.ssh/OVZ-STORAGE-128
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Exécution manuelle</strong> pour authentifier la clé avec utilisateur “debian”</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
sshfs -o allow_other usernl@xoyaz.xyz:/home/usernl/backup /opt/sshfs -C -p 55036 -oIdentityFile=/home/debian/.ssh/OVZ-STORAGE-128
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The authenticity of host <span class="s1">'[5.2.79.107]:55036 ([5.2.79.127]:55036)'</span> can<span class="s1">'t be established.
|
|||
|
ECDSA key fingerprint is SHA256:PDXQBhTh4oj0cSzgnjCun+J60JDUEk7VeLH2YHZbwMc.
|
|||
|
Are you sure you want to continue connecting (yes/no)? yes
|
|||
|
</span></code></pre></div></div>
|
|||
|
|
|||
|
<blockquote>
|
|||
|
<p>NOTE: Il faut mettre l’adresse IP du serveur , si les domaines peuvent ne pas être “résolus”</p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<p>Après vérification , <code class="language-plaintext highlighter-rouge">ls /opt/sshfs</code> , déconnexion <code class="language-plaintext highlighter-rouge">fusermount -u /opt/sshfs</code></p>
|
|||
|
|
|||
|
<p><strong>Montage fstab</strong></p>
|
|||
|
|
|||
|
<p>ajouter les lignes suivantes au fichier <strong>/etc/fstab</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>usernl@xoyaz.xyz:/home/usernl/backup /opt/sshfs fuse.sshfs _netdev,identityfile=/home/debian/.ssh/OVZ-STORAGE-128,allow_other,port=55036 0 0
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Montage pour authentifier la clé avec utilisateur “root”</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mount -a
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérification</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ls /opt/sshfs
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CalibreTechnique musique yunohost.backup.cinay.xyz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="wireguard">Wireguard</h2>
|
|||
|
|
|||
|
<p><img src="/images/wireguard-vpn.png" alt="Wireguard" width="150" /></p>
|
|||
|
|
|||
|
<p><em>WireGuard est un serveur VPN à code source ouvert, gratuit, moderne et rapide, doté d’une cryptographie de pointe. Il est plus rapide et plus simple que l’IPSec et l’OpenVPN</em></p>
|
|||
|
|
|||
|
<h3 id="installation-1">Installation</h3>
|
|||
|
|
|||
|
<p>En mode su</p>
|
|||
|
|
|||
|
<p>Wireguard est dans le noyau 5.6+ , les dépendances sont inutiles avec ce noyau</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install --no-install-recommends wireguard-tools
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Générer une paire de clés</strong></p>
|
|||
|
|
|||
|
<p>On se positionne dans le dossier <strong>/etc/wireguard/</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /etc/wireguard
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>WireGuard repose sur une authentification par clé publique/privée (cryptographie asymétrique), vous devez donc créer ces clés avec les sous-commandes wg genkey et wg pubkey<br />
|
|||
|
La création de la clé privée se fait avec wg genkey et la clé publique est générée en la canalisant dans wg pubkey</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>umask 077; wg genkey | tee vps506197-private.key | wg pubkey > vps506197-public.key
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Copier le contenu des clés dans un gestionnaire de mot de passe puis effacer les 2 fichiers</strong></p>
|
|||
|
|
|||
|
<p>**Autoriser le serveur Wireguard à relayer les paquets **</p>
|
|||
|
|
|||
|
<p>Autoriser le serveur Wireguard à relayer les paquets venant de ces clients vers l’internet et de traiter les paquets retours (modifier <strong>/etc/sysctl.conf</strong>)</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sed</span> <span class="nt">-i</span> <span class="s1">'s/^#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/'</span> /etc/sysctl.conf
|
|||
|
<span class="nb">sed</span> <span class="nt">-i</span> <span class="s1">'s/^#net.ipv6.conf.all.forwarding=1/net.ipv6.conf.all.forwarding=1/'</span> /etc/sysctl.conf
|
|||
|
sysctl <span class="nt">-p</span> <span class="c"># prise en compte immédiate</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="configuration-etcwireguardwg0conf">configuration /etc/wireguard/wg0.conf</h3>
|
|||
|
|
|||
|
<p>Récupérer le nom de la carte réseau <code class="language-plaintext highlighter-rouge">ip a</code> , dans notre cas <strong>eth0</strong></p>
|
|||
|
|
|||
|
<p>La première étape consiste à choisir une plage IPV4 privée qui sera utilisée par le serveur : <strong>10.55.22.0/8</strong></p>
|
|||
|
|
|||
|
<p>Pour une adresse IPV6 <a href="https://www.ultratools.com/tools/rangeGenerator">Local IPv6 Address Generator</a> : fd87:9aa8:e67c:5a80::/64</p>
|
|||
|
|
|||
|
<table>
|
|||
|
<thead>
|
|||
|
<tr>
|
|||
|
<th>Prefix/L</th>
|
|||
|
<th>fd</th>
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<tr>
|
|||
|
<td>Global ID</td>
|
|||
|
<td>879aa8e67c</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>Subnet ID</td>
|
|||
|
<td>5a80</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>Combine/CID</td>
|
|||
|
<td>fd87:9aa8:e67c:5a80::/64</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>IPv6 addresses</td>
|
|||
|
<td>fd87:9aa8:e67c:5a80::/64:XXXX:XXXX:XXXX:XXXX</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>Start Range</td>
|
|||
|
<td>fd87:9aa8:e67c:5a80:0:0:0:0</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>End Range</td>
|
|||
|
<td>fd87:9aa8:e67c:5a80:ffff:ffff:ffff:ffff</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>No. of hosts</td>
|
|||
|
<td>18446744073709551616</td>
|
|||
|
</tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
|
|||
|
<p>Nous utiliserons 10.55.22.0/24 qui se trouve dans la plage 10.55.22.0/8 . Le serveur aura l’adresse IP suivante: 10.55.22.1 . Il est également nécessaire de choisir un port, qui sera exposé publiquement, pour que le serveur écoute.Le port de documentation standard est généralement 51820.</p>
|
|||
|
|
|||
|
<p>Créer le fichier <strong>/etc/wireguard/wg0.conf</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /etc/wireguard/wg0.conf
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-conf highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[<span class="n">Interface</span>]
|
|||
|
<span class="n">Address</span> = <span class="m">10</span>.<span class="m">55</span>.<span class="m">22</span>.<span class="m">1</span>/<span class="m">24</span>
|
|||
|
<span class="n">Address</span> = <span class="n">fd87</span>:<span class="m">9</span><span class="n">aa8</span>:<span class="n">e67c</span>:<span class="m">5</span><span class="n">a80</span>::<span class="m">1</span>/<span class="m">64</span>
|
|||
|
<span class="n">ListenPort</span> = <span class="m">51820</span>
|
|||
|
<span class="n">PostUp</span> = <span class="n">iptables</span> -<span class="n">A</span> <span class="n">FORWARD</span> -<span class="n">i</span> <span class="n">wg0</span> -<span class="n">j</span> <span class="n">ACCEPT</span>; <span class="n">iptables</span> -<span class="n">t</span> <span class="n">nat</span> -<span class="n">A</span> <span class="n">POSTROUTING</span> -<span class="n">o</span> <span class="n">eth0</span> -<span class="n">j</span> <span class="n">MASQUERADE</span>; <span class="n">ip6tables</span> -<span class="n">A</span> <span class="n">FORWARD</span> -<span class="n">i</span> <span class="n">wg0</span> -<span class="n">j</span> <span class="n">ACCEPT</span>; <span class="n">ip6tables</span> -<span class="n">t</span> <span class="n">nat</span> -<span class="n">A</span> <span class="n">POSTROUTING</span> -<span class="n">o</span> <span class="n">eth0</span> -<span class="n">j</span> <span class="n">MASQUERADE</span>
|
|||
|
<span class="n">PostDown</span> = <span class="n">iptables</span> -<span class="n">D</span> <span class="n">FORWARD</span> -<span class="n">i</span> <span class="n">wg0</span> -<span class="n">j</span> <span class="n">ACCEPT</span>; <span class="n">iptables</span> -<span class="n">t</span> <span class="n">nat</span> -<span class="n">D</span> <span class="n">POSTROUTING</span> -<span class="n">o</span> <span class="n">eth0</span> -<span class="n">j</span> <span class="n">MASQUERADE</span>; <span class="n">ip6tables</span> -<span class="n">D</span> <span class="n">FORWARD</span> -<span class="n">i</span> <span class="n">wg0</span> -<span class="n">j</span> <span class="n">ACCEPT</span>; <span class="n">ip6tables</span> -<span class="n">t</span> <span class="n">nat</span> -<span class="n">D</span> <span class="n">POSTROUTING</span> -<span class="n">o</span> <span class="n">eth0</span> -<span class="n">j</span> <span class="n">MASQUERADE</span>
|
|||
|
<span class="n">PrivateKey</span> = <span class="m">5</span><span class="n">Zsr0jQXiuCpHFkye325Zsr0jMUKinVEOPmk</span>=
|
|||
|
<span class="n">DNS</span> = <span class="m">10</span>.<span class="m">55</span>.<span class="m">22</span>.<span class="m">1</span>
|
|||
|
<span class="n">DNS</span> = <span class="n">fd87</span>:<span class="m">9</span><span class="n">aa8</span>:<span class="n">e67c</span>:<span class="m">5</span><span class="n">a80</span>::<span class="m">1</span>
|
|||
|
<span class="n">SaveConfig</span> = <span class="n">true</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Address</strong> , fixer l’adresse IP privée du serveur à l’intérieur du VPN.Les adresses du réseau VPN de 10.55.22.0 à 10.55.22.255 sont fixées par le masque <strong>/24</strong><br />
|
|||
|
<strong>PostUp</strong> , pour la mise en place des règles iptables de translation d’adresses à l’activation du VPN (autoriser le routage des paquets réseau venant des clients vers internet)<br />
|
|||
|
<strong>PostDown</strong> , pour la suppression des règles iptables de translation d’adresses à l’arrêt du VPN<br />
|
|||
|
<strong>PrivateKey</strong> , clé privée du serveur</p>
|
|||
|
|
|||
|
<p>Modification des droits (lecture uniquement par “root”)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod 600 /etc/wireguard/wg0.conf
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="ouvrir-le-port-51820">Ouvrir le port 51820</h3>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost firewall allow UDP 51820 # wireguard
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="dns---dnsmasq">DNS - dnsmasq</h3>
|
|||
|
|
|||
|
<p>Ajouter une configuration dnsmasq <strong>wireguard</strong> pour y ajouter les adresses ip du serveur <code class="language-plaintext highlighter-rouge">127.0.0.1,10.55.22.1,fd87:9aa8:e67c:5a80::1</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/dnsmasq.d/wireguard
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>listen-address<span class="o">=</span>127.0.0.1,10.55.22.1,fd87:9aa8:e67c:5a80::1
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Relancer le service</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart dnsmasq
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="wireguard-web-wgcinayeu">Wireguard web (wg.cinay.eu)</h3>
|
|||
|
|
|||
|
<h4 id="installation-wg-gen-web">Installation wg-gen-web</h4>
|
|||
|
|
|||
|
<p>Création dossier application web</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir -p /opt/appwg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Copier le git wg-gen-web</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~
|
|||
|
git clone https://gitea.cinay.eu/yann/wg-gen-web.git
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Construction du site</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo ln</span> <span class="nt">-s</span> <span class="nv">$HOME</span>/wg-gen-web /usr/local/go/src/wg-gen-web
|
|||
|
<span class="nb">cd</span> <span class="nv">$HOME</span>/wg-gen-web/cmd/wg-gen-web/
|
|||
|
go build <span class="nt">-o</span> deb-wg-gen-web
|
|||
|
<span class="nb">cd</span> ../../ui
|
|||
|
npm <span class="nb">install
|
|||
|
</span>npm run build
|
|||
|
<span class="nb">sudo cp</span> <span class="nv">$HOME</span>/wg-gen-web/cmd/wg-gen-web/deb-wg-gen-web /opt/appwg
|
|||
|
<span class="nb">sudo mkdir</span> <span class="nt">-p</span> /opt/appwg/ui
|
|||
|
<span class="nb">sudo cp</span> <span class="nt">-r</span> <span class="nv">$HOME</span>/wg-gen-web/ui/dist /opt/appwg/ui/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="configuration-fichier-env">Configuration fichier .env</h4>
|
|||
|
|
|||
|
<p>Créer le fichier de configuration <strong>.env</strong> (pas de oath et messagerie) à partir du modèle</p>
|
|||
|
|
|||
|
<p>Dans le cas ou l’autorisation à 2 facteurs n’est pas utilisée, le fichier <strong>/opt/appwg/.env</strong> se résume à remplir la zone correspondante SMTP de la messagerie et désactiver l’autorisation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /opt/appwg/.env
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<pre><code class="language-env"># IP address to listen to
|
|||
|
SERVER=0.0.0.0
|
|||
|
# port to bind
|
|||
|
PORT=8080
|
|||
|
# Gin framework release mode
|
|||
|
GIN_MODE=release
|
|||
|
# where to write all generated config files
|
|||
|
WG_CONF_DIR=/etc/wireguard
|
|||
|
# WireGuard main config file name, generally <interface name>.conf
|
|||
|
WG_INTERFACE_NAME=wg0.conf
|
|||
|
|
|||
|
# SMTP settings to send email to clients
|
|||
|
SMTP_HOST=smtp.gmail.com
|
|||
|
SMTP_PORT=587
|
|||
|
SMTP_USERNAME=account@gmail.com
|
|||
|
SMTP_PASSWORD=*************
|
|||
|
SMTP_FROM=Wg Gen Web <account@gmail.com>
|
|||
|
|
|||
|
# set provider name to fake to disable auth, also the default
|
|||
|
OAUTH2_PROVIDER_NAME=fake
|
|||
|
</code></pre>
|
|||
|
|
|||
|
<h4 id="création-service-wgweb">Création service wgweb</h4>
|
|||
|
|
|||
|
<p>Créer un service systemd <strong>wgweb</strong> qui lance le serveur avec journalisation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/systemd/system/wgweb.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Unit]</span>
|
|||
|
<span class="py">Description</span><span class="p">=</span><span class="s">Gestion web wg</span>
|
|||
|
<span class="py">After</span><span class="p">=</span><span class="s">network.target</span>
|
|||
|
|
|||
|
<span class="nn">[Service]</span>
|
|||
|
|
|||
|
<span class="py">Type</span><span class="p">=</span><span class="s">simple</span>
|
|||
|
|
|||
|
<span class="py">Restart</span><span class="p">=</span><span class="s">on-failure</span>
|
|||
|
<span class="py">RestartSec</span><span class="p">=</span><span class="s">10</span>
|
|||
|
|
|||
|
<span class="py">WorkingDirectory</span><span class="p">=</span><span class="s">/opt/appwg</span>
|
|||
|
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/opt/appwg/deb-wg-gen-web</span>
|
|||
|
|
|||
|
<span class="nn">[Install]</span>
|
|||
|
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Recharger <code class="language-plaintext highlighter-rouge">systemd</code> et activer le service</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl daemon-reload
|
|||
|
sudo systemctl enable wgweb.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="paramètrage-serveur-wg0conf-et-serverjson">Paramètrage serveur (wg0.conf et server.json)</h4>
|
|||
|
|
|||
|
<p>Créer le fichier <strong>/etc/wireguard/server.json</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/wireguard/server.json
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
|
|||
|
</span><span class="nl">"address"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
|
|||
|
</span><span class="s2">"fd87:9aa8:e67c:5a80::1/64"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="s2">"10.55.22.1/24"</span><span class="w">
|
|||
|
</span><span class="p">],</span><span class="w">
|
|||
|
</span><span class="nl">"listenPort"</span><span class="p">:</span><span class="w"> </span><span class="mi">51820</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"mtu"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"privateKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"UEQCgh/6a2RQbF9+qqylVjqLCK/mRwqRPc/4vjRsYXg="</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"publicKey"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0s1wsNpuU1RlKgj6AmoN0aKUeb+aESByhO3yTSnfTyE="</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"endpoint"</span><span class="p">:</span><span class="w"> </span><span class="s2">"164.132.104.145:51820"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"persistentKeepalive"</span><span class="p">:</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"dns"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
|
|||
|
</span><span class="s2">"fd87:9aa8:e67c:5a80::1"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="s2">"10.55.22.1"</span><span class="w">
|
|||
|
</span><span class="p">],</span><span class="w">
|
|||
|
</span><span class="nl">"allowedips"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
|
|||
|
</span><span class="s2">"0.0.0.0/0"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="s2">"::/0"</span><span class="w">
|
|||
|
</span><span class="p">],</span><span class="w">
|
|||
|
</span><span class="nl">"preUp"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"postUp"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"preDown"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"postDown"</span><span class="p">:</span><span class="w"> </span><span class="s2">"iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"updatedBy"</span><span class="p">:</span><span class="w"> </span><span class="s2">"n"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"created"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-05-17T21:00:00.589913433Z"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"updated"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2020-05-17T21:05:00.466114026Z"</span><span class="w">
|
|||
|
</span><span class="p">}</span><span class="w">
|
|||
|
</span></code></pre></div></div>
|
|||
|
|
|||
|
<p>Démarrer le service</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start wgweb.service
|
|||
|
sudo systemctl status wgweb.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>● wgweb.service - Gestion web wg
|
|||
|
Loaded: loaded <span class="o">(</span>/etc/systemd/system/wgweb.service<span class="p">;</span> enabled<span class="p">;</span> vendor preset: enabled<span class="o">)</span>
|
|||
|
Active: active <span class="o">(</span>running<span class="o">)</span> since Thu 2020-06-18 14:47:13 CEST<span class="p">;</span> 13s ago
|
|||
|
Main PID: 20718 <span class="o">(</span>deb-wg-gen-web<span class="o">)</span>
|
|||
|
Tasks: 5 <span class="o">(</span>limit: 4593<span class="o">)</span>
|
|||
|
Memory: 6.8M
|
|||
|
CGroup: /system.slice/wgweb.service
|
|||
|
└─20718 /opt/appwg/deb-wg-gen-web
|
|||
|
|
|||
|
Jun 18 14:47:13 cinay.eu systemd[1]: Started Gestion web wg.
|
|||
|
Jun 18 14:47:13 cinay.eu deb-wg-gen-web[20718]: <span class="nb">time</span><span class="o">=</span><span class="s2">"2020-06-18T14:47:13+02:00"</span> <span class="nv">level</span><span class="o">=</span>info <span class="nv">msg</span><span class="o">=</span><span class="s2">"Lancement de la version Web de Wg Gen : yann"</span>
|
|||
|
Jun 18 14:47:13 cinay.eu deb-wg-gen-web[20718]: <span class="nb">time</span><span class="o">=</span><span class="s2">"2020-06-18T14:47:13+02:00"</span> <span class="nv">level</span><span class="o">=</span>warning <span class="nv">msg</span><span class="o">=</span><span class="s2">"Oauth n'est pas utilisé, aucune authentification réelle ne sera effectuée"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour suivre dans le journal</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo journalctl -f -t deb-wg-gen-web
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--</span> Logs begin at Sun 2020-05-17 13:06:29 CEST. <span class="nt">--</span>
|
|||
|
May 17 21:21:23 cinay.eu deb-wg-gen-web[30596]: <span class="nb">time</span><span class="o">=</span><span class="s2">"2020-05-17T21:21:23+02:00"</span> <span class="nv">level</span><span class="o">=</span>info <span class="nv">msg</span><span class="o">=</span><span class="s2">"Lancement de la version Web de Wg Gen : yann"</span>
|
|||
|
May 17 21:21:23 cinay.eu deb-wg-gen-web[30596]: <span class="nb">time</span><span class="o">=</span><span class="s2">"2020-05-17T21:21:23+02:00"</span> <span class="nv">level</span><span class="o">=</span>warning <span class="nv">msg</span><span class="o">=</span><span class="s2">"Oauth n'est pas utilisé, aucune authentification réelle ne sera effectuée"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="activation-service-wireguard-wg-quickwg0service">Activation service wireguard wg-quick@wg0.service</h4>
|
|||
|
|
|||
|
<p>Le gestionnaire web est à jour , on peut lancer le serveur wireguard</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start wg-quick@wg0.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérifier</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl status wg-quick@wg0.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>● wg-quick@wg0.service - WireGuard via wg-quick<span class="o">(</span>8<span class="o">)</span> <span class="k">for </span>wg0
|
|||
|
Loaded: loaded <span class="o">(</span>/lib/systemd/system/wg-quick@.service<span class="p">;</span> disabled<span class="p">;</span> vendor preset: enabled<span class="o">)</span>
|
|||
|
Active: active <span class="o">(</span>exited<span class="o">)</span> since Thu 2020-06-18 14:54:23 CEST<span class="p">;</span> 8s ago
|
|||
|
Docs: man:wg-quick<span class="o">(</span>8<span class="o">)</span>
|
|||
|
man:wg<span class="o">(</span>8<span class="o">)</span>
|
|||
|
https://www.wireguard.com/
|
|||
|
https://www.wireguard.com/quickstart/
|
|||
|
https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
|
|||
|
https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
|
|||
|
Process: 1404 <span class="nv">ExecStart</span><span class="o">=</span>/usr/bin/wg-quick up wg0 <span class="o">(</span><span class="nv">code</span><span class="o">=</span>exited, <span class="nv">status</span><span class="o">=</span>0/SUCCESS<span class="o">)</span>
|
|||
|
Main PID: 1404 <span class="o">(</span><span class="nv">code</span><span class="o">=</span>exited, <span class="nv">status</span><span class="o">=</span>0/SUCCESS<span class="o">)</span>
|
|||
|
|
|||
|
Jun 18 14:54:23 cinay.eu systemd[1]: Starting WireGuard via wg-quick<span class="o">(</span>8<span class="o">)</span> <span class="k">for </span>wg0...
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#]</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip link add wg0 type wireguard</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] wg setconf wg0 /dev/fd/63</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip -6 address add fd87:9aa8:e67c:5a80::1/64 dev wg0</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip -4 address add 10.55.22.1/24 dev wg0</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip link set mtu 1420 up dev wg0</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE</span>
|
|||
|
Jun 18 14:54:23 cinay.eu systemd[1]: Started WireGuard via wg-quick<span class="o">(</span>8<span class="o">)</span> <span class="k">for </span>wg0.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Activer</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable wg-quick@wg0.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="modification-automatique-du-paramétrage-wireguard">Modification automatique du paramétrage WireGuard</h4>
|
|||
|
|
|||
|
<p>Utilisation de <strong>systemd.path</strong> monitor pour les changements dans le répertoire, voir <a href="https://www.freedesktop.org/software/systemd/man/systemd.path.html">systemd doc</a></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/systemd/system/wg-gen-web.path
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Unit]</span>
|
|||
|
<span class="py">Description</span><span class="p">=</span><span class="s">Surveiller /etc/wireguard pour les changements</span>
|
|||
|
|
|||
|
<span class="nn">[Path]</span>
|
|||
|
<span class="py">PathModified</span><span class="p">=</span><span class="s">/etc/wireguard</span>
|
|||
|
|
|||
|
<span class="nn">[Install]</span>
|
|||
|
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ce <strong>wg-gen-web.path</strong> activera le fichier de l’unité avec le même nom, <strong>wg-gen-web.service</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/systemd/system/wg-gen-web.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Unit]</span>
|
|||
|
<span class="py">Description</span><span class="p">=</span><span class="s">Relancer WireGuard si changements</span>
|
|||
|
<span class="py">After</span><span class="p">=</span><span class="s">network.target</span>
|
|||
|
|
|||
|
<span class="nn">[Service]</span>
|
|||
|
<span class="py">Type</span><span class="p">=</span><span class="s">oneshot</span>
|
|||
|
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/usr/bin/systemctl restart wg-quick@wg0.service</span>
|
|||
|
|
|||
|
<span class="nn">[Install]</span>
|
|||
|
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ce qui permettra de relancer le service WireGuard</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start wg-gen-web.path
|
|||
|
sudo systemctl status wg-gen-web.path
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>● wg-gen-web.path - Surveiller /etc/wireguard pour les changements
|
|||
|
Loaded: loaded <span class="o">(</span>/etc/systemd/system/wg-gen-web.path<span class="p">;</span> disabled<span class="p">;</span> vendor preset: enabled<span class="o">)</span>
|
|||
|
Active: active <span class="o">(</span>waiting<span class="o">)</span> since Thu 2020-06-18 14:56:46 CEST<span class="p">;</span> 29ms ago
|
|||
|
|
|||
|
Jun 18 14:56:46 cinay.eu systemd[1]: Started Surveiller /etc/wireguard pour les changements.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Activation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable wg-gen-web.path
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour suivre dans le journal</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo journalctl -f -t wg-quick
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">--</span> Logs begin at Thu 2020-06-18 14:50:27 CEST. <span class="nt">--</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#]</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip link add wg0 type wireguard</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] wg setconf wg0 /dev/fd/63</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip -6 address add fd87:9aa8:e67c:5a80::1/64 dev wg0</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip -4 address add 10.55.22.1/24 dev wg0</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] ip link set mtu 1420 up dev wg0</span>
|
|||
|
Jun 18 14:54:23 cinay.eu wg-quick[1404]: <span class="o">[</span><span class="c">#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="le-site-web-wireguard-wgcinayeu">Le site web wireguard (wg.cinay.eu)</h4>
|
|||
|
|
|||
|
<p>Créer le domaine wg.cinay.eu et les certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
yunohost domain add wg.cinay.eu
|
|||
|
yunohost domain cert-install wg.cinay.eu --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer application Multi web app</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
git clone https://gitea.cinay.eu/yann/multi_webapp_buster_ynh
|
|||
|
yunohost app install multi_webapp_buster_ynh/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DANGER! This app is not part of Yunohost<span class="s1">'s app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn'</span>t work or breaks your system… If you are willing to take that risk anyway, <span class="nb">type</span> <span class="s1">'Yes, I understand'</span>: Yes, I understand
|
|||
|
Available domains:
|
|||
|
- cinay.eu
|
|||
|
- wg.cinay.eu
|
|||
|
Choose a domain <span class="k">for </span>your Webapp <span class="o">(</span>default: cinay.eu<span class="o">)</span>: wg.cinay.eu
|
|||
|
Choose a path <span class="k">for </span>your Webapp <span class="o">(</span>default: /site<span class="o">)</span>: /
|
|||
|
Available <span class="nb">users</span>:
|
|||
|
- yann
|
|||
|
Choose the YunoHost user: yann
|
|||
|
Create a database? <span class="o">[</span><span class="nb">yes</span> | no] <span class="o">(</span>default: no<span class="o">)</span>:
|
|||
|
Is it a public website ? <span class="o">[</span><span class="nb">yes</span> | no] <span class="o">(</span>default: no<span class="o">)</span>:
|
|||
|
Info: Installing the app <span class="s1">'multi_webapp'</span>…
|
|||
|
Info: <span class="o">[</span>+...................] <span class="o">></span> Retrieve arguments from the manifest
|
|||
|
Info: <span class="o">[</span><span class="c">#+..................] > Check if the app can be installed</span>
|
|||
|
Info: <span class="o">[</span><span class="c">##+++...............] > Store settings from manifest</span>
|
|||
|
Info: <span class="o">[</span><span class="c">#####+..............] > Setup SSOwat</span>
|
|||
|
Info: <span class="o">[</span><span class="c">######+.............] > Create final path</span>
|
|||
|
Info: The directory /var/www/webapp_yann already exist, <span class="k">do </span>not recreate it.
|
|||
|
Info: <span class="o">[</span><span class="c">#######+++..........] > Create a dedicated user</span>
|
|||
|
Info: <span class="o">[</span><span class="c">##########+.........] > Configure php-fpm</span>
|
|||
|
Info: <span class="o">[</span><span class="c">###########+........] > Configure nginx</span>
|
|||
|
Info: <span class="o">[</span><span class="c">############+++++...] > Reload nginx</span>
|
|||
|
Info: <span class="o">[</span><span class="c">####################] > Installation completed</span>
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Proxy nginx</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mv /etc/nginx/conf.d/wg.cinay.eu.d/webapp_wg.cinay.eu_.conf /etc/nginx/conf.d/wg.cinay.eu.d/webapp_wg.cinay.eu_.conf.SAV
|
|||
|
sudo nano /etc/nginx/conf.d/wg.cinay.eu.d/webapp_wg.cinay.eu_.conf
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#sub_path_only rewrite ^/$ / permanent;</span>
|
|||
|
<span class="k">location</span> <span class="n">/</span> <span class="p">{</span>
|
|||
|
<span class="kn">proxy_pass</span> <span class="s">http://127.0.0.1:8080/</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_buffering</span> <span class="no">off</span><span class="p">;</span>
|
|||
|
<span class="kn">fastcgi_param</span> <span class="s">REMOTE_USER</span> <span class="nv">$remote_user</span><span class="p">;</span>
|
|||
|
<span class="kn">client_max_body_size</span> <span class="mi">50M</span><span class="p">;</span>
|
|||
|
<span class="kn">more_set_input_headers</span> <span class="s">'Authorization:</span> <span class="nv">$http_authorization</span><span class="s">'</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">Authorization</span> <span class="nv">$http_authorization</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># Include SSOWAT user panel.</span>
|
|||
|
<span class="kn">include</span> <span class="s">conf.d/yunohost_panel.conf.inc</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>On vérifie et on relance le serveur nginx</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nginx -t
|
|||
|
sudo systemctl reload nginx
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Changer libellé (en mode administration) : <strong>Wireguard Web Admin</strong><br />
|
|||
|
Accès https://wg.cinay.eu</p>
|
|||
|
|
|||
|
<h2 id="audio-streaming">Audio streaming</h2>
|
|||
|
|
|||
|
<p><em>Au choix Gonic ou Navidrome (pas les deux!)</em></p>
|
|||
|
|
|||
|
<h3 id="gonic-inactif">Gonic (INACTIF)</h3>
|
|||
|
|
|||
|
<p><img src="/images/gonic002.png" alt="" width="100" /><br />
|
|||
|
<em><a href="https://github.com/sentriz/gonic">Gonic</a> écrit en go est une alternative à Subsonic.org, accessible par un proxy nginx qui accepte de fonctionner avec répertoires montés par FUSE.</em></p>
|
|||
|
|
|||
|
<h4 id="installation-gonic">Installation gonic</h4>
|
|||
|
|
|||
|
<p>dans le répertoire utilisateur <strong>$HOME</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># les dépendances
|
|||
|
sudo apt install build-essential git sqlite libtag1-dev ffmpeg libasound2-dev pkg-config # for debian like
|
|||
|
cd $HOME/
|
|||
|
# cloner
|
|||
|
git clone https://gitea.cinay.eu/yann/golang-subsonic.git
|
|||
|
cd golang-subsonic/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Construire l’exécutable “gonic” et le copier dans /usr/local/bin</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./_do_build_server
|
|||
|
sudo mv gonic /usr/local/bin/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer le dossier pour la base</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir -p /opt/gonic
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="créer-le-service-gonic">Créer le service gonic</h4>
|
|||
|
|
|||
|
<p>Que fait le service ?</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>Le dossier fuse est monté au démarrage par fstab</li>
|
|||
|
<li>lancer le serveur “gonic” en écoute local sur le port 4747 avec les options <code class="language-plaintext highlighter-rouge">-music-path</code>, <code class="language-plaintext highlighter-rouge">-db-path</code> et <code class="language-plaintext highlighter-rouge">-proxy-prefix</code></li>
|
|||
|
<li>A l’arrêt,tuer la tâche “gonic”</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Tester le serveur</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
/usr/local/bin/gonic -music-path /opt/sshfs/musique -db-path /opt/gonic/gonic.db -proxy-prefix /
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2020/05/19 17:56:37 starting gonic v0.8.8
|
|||
|
2020/05/19 17:56:37 provided config
|
|||
|
2020/05/19 17:56:37 cache-path /tmp/gonic_cache
|
|||
|
2020/05/19 17:56:37 config-path
|
|||
|
2020/05/19 17:56:37 db-path /opt/gonic/gonic.db
|
|||
|
2020/05/19 17:56:37 jukebox-enabled false
|
|||
|
2020/05/19 17:56:37 listen-addr 0.0.0.0:4747
|
|||
|
2020/05/19 17:56:37 music-path /opt/sshfs/musique
|
|||
|
2020/05/19 17:56:37 proxy-prefix /
|
|||
|
2020/05/19 17:56:37 scan-interval 0
|
|||
|
2020/05/19 17:56:37 version false
|
|||
|
2020/05/19 17:56:37 migration (1/7) '202002192100' finished
|
|||
|
2020/05/19 17:56:37 migration (2/7) '202002192019' finished
|
|||
|
2020/05/19 17:56:37 migration (3/7) '202002192222' finished
|
|||
|
2020/05/19 17:56:37 migration (4/7) '202003111222' finished
|
|||
|
2020/05/19 17:56:37 migration (5/7) '202003121330' finished
|
|||
|
2020/05/19 17:56:37 migration (6/7) '202003241509' finished
|
|||
|
2020/05/19 17:56:37 migration (7/7) '202004302006' finished
|
|||
|
2020/05/19 17:56:37 starting job 'http'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Arrêt par Ctrl+C</p>
|
|||
|
|
|||
|
<p>Chaque service généré par systemd est configuré par un fichier .service qui se trouve dans le répertoire <strong>/etc/systemd/system</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/systemd/system/gonic.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
|
|||
|
Description=Gonic audio server
|
|||
|
After=network.target
|
|||
|
|
|||
|
[Service]
|
|||
|
Type=simple
|
|||
|
|
|||
|
Restart=on-failure
|
|||
|
RestartSec=10
|
|||
|
|
|||
|
ExecStart=/usr/local/bin/gonic -music-path /opt/sshfs/musique -db-path /opt/gonic/gonic.db -proxy-prefix /
|
|||
|
|
|||
|
[Install]
|
|||
|
WantedBy=multi-user.target
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Recharger <code class="language-plaintext highlighter-rouge">systemd</code> puis démarrer le service:</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl daemon-reload
|
|||
|
sudo systemctl start gonic.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Visualiser le journal</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo journalctl -t gonic
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-- Logs begin at Thu 2020-06-18 14:50:27 CEST, end at Thu 2020-06-18 15:26:43 CEST. --
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 starting gonic v0.8.8
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 provided config
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 cache-path /tmp/gonic_cache
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 config-path
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 db-path /opt/gonic/gonic.db
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 jukebox-enabled false
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 listen-addr 0.0.0.0:4747
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 music-path /opt/sshfs/musique
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 proxy-prefix /
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 scan-interval 0
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 version false
|
|||
|
Jul 19 17:47:22 cinay.eu gonic[636]: 2020/07/19 17:47:22 starting job 'http'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Si tout est en ordre , on active le service</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable gonic.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour une désactivation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop gonic.service
|
|||
|
sudo systemctl disable gonic.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="navidrome">Navidrome</h3>
|
|||
|
|
|||
|
<p><em><a href="https://www.navidrome.org/docs/installation/pre-built-binaries/">Navidrome</a> est un serveur de collecte de musique et de streaming sur le web, à code source ouvert. Il vous donne la liberté d’écouter votre
|
|||
|
collection de musique à partir de n’importe quel navigateur ou appareil mobile. C’est comme votre Spotify personnel !</em></p>
|
|||
|
|
|||
|
<h4 id="installation-navidrome">Installation Navidrome</h4>
|
|||
|
|
|||
|
<p>Créer les répertoires</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo install -d -o debian -g debian /opt/navidrome
|
|||
|
sudo install -d -o debian -g debian /var/lib/navidrome
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>La <a href="https://github.com/deluan/navidrome/releases">dernière version</a></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://github.com/deluan/navidrome/releases/download/v0.35.1/navidrome_0.35.1_Linux_x86_64.tar.gz -O Navidrome.tar.gz
|
|||
|
sudo tar -xvzf Navidrome.tar.gz -C /opt/navidrome/
|
|||
|
sudo chown -R debian:debian /opt/navidrome
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer le fichier de configuration <code class="language-plaintext highlighter-rouge">/var/lib/navidrome/navidrome.toml</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MusicFolder = "/opt/sshfs/musique"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="créer-le-service-navidrome">Créer le service navidrome</h4>
|
|||
|
|
|||
|
<p>Créer un service <code class="language-plaintext highlighter-rouge">/etc/systemd/system/navidrome.service</code> en mode su</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Unit]
|
|||
|
Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic
|
|||
|
After=remote-fs.target network.target
|
|||
|
AssertPathExists=/var/lib/navidrome
|
|||
|
|
|||
|
[Install]
|
|||
|
WantedBy=multi-user.target
|
|||
|
|
|||
|
[Service]
|
|||
|
User=debian
|
|||
|
Group=debian
|
|||
|
Type=simple
|
|||
|
ExecStart=/opt/navidrome/navidrome --configfile "/var/lib/navidrome/navidrome.toml"
|
|||
|
WorkingDirectory=/var/lib/navidrome
|
|||
|
TimeoutStopSec=20
|
|||
|
KillMode=process
|
|||
|
Restart=on-failure
|
|||
|
|
|||
|
# See https://www.freedesktop.org/software/systemd/man/systemd.exec.html
|
|||
|
DevicePolicy=closed
|
|||
|
NoNewPrivileges=yes
|
|||
|
PrivateTmp=yes
|
|||
|
PrivateUsers=yes
|
|||
|
ProtectControlGroups=yes
|
|||
|
ProtectKernelModules=yes
|
|||
|
ProtectKernelTunables=yes
|
|||
|
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
|||
|
RestrictNamespaces=yes
|
|||
|
RestrictRealtime=yes
|
|||
|
SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap
|
|||
|
ReadWritePaths=/var/lib/navidrome
|
|||
|
|
|||
|
# You can uncomment the following line if you're not using the jukebox This
|
|||
|
# will prevent navidrome from accessing any real (physical) devices
|
|||
|
#PrivateDevices=yes
|
|||
|
|
|||
|
# You can change the following line to `strict` instead of `full` if you don't
|
|||
|
# want navidrome to be able to write anything on your filesystem outside of
|
|||
|
# /var/lib/navidrome.
|
|||
|
ProtectSystem=full
|
|||
|
|
|||
|
# You can comment the following line if you don't have any media in /home/*.
|
|||
|
# This will prevent navidrome from ever reading/writing anything there.
|
|||
|
#ProtectHome=true
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Démarrer le service</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl daemon-reload
|
|||
|
sudo systemctl start navidrome.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le status</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl status navidrome.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>● navidrome.service - Navidrome Music Server and Streamer compatible with Subsonic/Airsonic
|
|||
|
Loaded: loaded (/etc/systemd/system/navidrome.service; disabled; vendor preset: enabled)
|
|||
|
Active: active (running) since Mon 2020-10-12 16:40:15 CEST; 10s ago
|
|||
|
Main PID: 23957 (navidrome)
|
|||
|
Tasks: 5 (limit: 4593)
|
|||
|
Memory: 14.5M
|
|||
|
CGroup: /system.slice/navidrome.service
|
|||
|
└─23957 /opt/navidrome/navidrome --configfile /var/lib/navidrome/navidrome.toml
|
|||
|
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=info msg="Configuring Media Folder" name="Music Library" path=/opt/sshfs/musique
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=info msg="Creating Transcoding cache" maxSize="100 MB" path=cache/transcoding
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=warning msg="Running initial setup"
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=warning msg="Creating JWT secret, used for encrypting UI sessions"
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=info msg="Starting scanner" interval=1m0s
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=info msg="Mounting routes" path=/rest
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=info msg="Mounting routes" path=/app
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=info msg="Login rate limit set" requestLimit=5 windowLength=20s
|
|||
|
Oct 12 16:40:15 cinay.eu navidrome[23957]: time="2020-10-12T16:40:15+02:00" level=info msg="Navidrome server is accepting requests" address="0.0.0.0:4533"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Activer</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable navidrome.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modier le binaire <code class="language-plaintext highlighter-rouge">navidrome</code> qui est situé dans le dossier <code class="language-plaintext highlighter-rouge">/opt/navidrome/</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop navidrome.service
|
|||
|
# Remplacer le binaire `/opt/navidrome/navidrome` par une version plus récente
|
|||
|
sudo systemctl start navidrome.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="ziccinayeu---domaine-et-proxy">zic.cinay.eu - domaine et proxy</h3>
|
|||
|
|
|||
|
<h4 id="créer-le-domaine-ziccinayeu">Créer le domaine zic.cinay.eu</h4>
|
|||
|
|
|||
|
<p>Créer le domaine zic.cinay.eu et les certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
yunohost domain add zic.cinay.eu
|
|||
|
yunohost domain cert-install zic.cinay.eu --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer l’application Multi web app sur le domaine zic.cinay.eu</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
git clone https://gitea.cinay.eu/yann/multi_webapp_buster_ynh
|
|||
|
yunohost app install multi_webapp_buster_ynh/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>...]
|
|||
|
Choose a domain <span class="k">for </span>your Webapp <span class="o">(</span>default: cinay.eu<span class="o">)</span>: zic.cinay.eu
|
|||
|
Choose a path <span class="k">for </span>your Webapp <span class="o">(</span>default: /site<span class="o">)</span>: /
|
|||
|
Available <span class="nb">users</span>:
|
|||
|
- yann
|
|||
|
Choose the YunoHost user: yann
|
|||
|
Create a database? <span class="o">[</span><span class="nb">yes</span> | no] <span class="o">(</span>default: no<span class="o">)</span>:
|
|||
|
Is it a public website ? <span class="o">[</span><span class="nb">yes</span> | no] <span class="o">(</span>default: no<span class="o">)</span>: <span class="nb">yes</span>
|
|||
|
<span class="o">[</span>...]
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Voir <a href="https://yunohost.org/#/groups_and_permissions">https://yunohost.org/#/groups_and_permissions</a></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost user permission list
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>permissions:
|
|||
|
mail.main:
|
|||
|
allowed: all_users
|
|||
|
multi_webapp.main:
|
|||
|
allowed: all_users
|
|||
|
multi_webapp__2.main:
|
|||
|
allowed:
|
|||
|
- visitors
|
|||
|
- all_users
|
|||
|
xmpp.main:
|
|||
|
allowed: all_users
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>On voit que <code class="language-plaintext highlighter-rouge">multi_webapp__2.main</code> (zic.cinay.eu) à un accès complet sans aucune autorisation<br />
|
|||
|
Changer le libellé en <strong>Zic Audio Server</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label multi_webapp__2 'Zic Audio Server'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="proxy-nginx">proxy nginx</h4>
|
|||
|
|
|||
|
<p><em>Gonic est un serveur local http sur le port 4747 , Navidrome est un serveur local http sur le port 4747</em></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mv /etc/nginx/conf.d/zic.cinay.eu.d/webapp_zic.cinay.eu_.conf /etc/nginx/conf.d/zic.cinay.eu.d/webapp_zic.cinay.eu_.conf.SAV
|
|||
|
sudo nano /etc/nginx/conf.d/wg.cinay.eu.d/webapp_wg.cinay.eu_.conf
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Proxy nginx</strong> - configuration <strong>/etc/nginx/conf.d/zic.cinay.eu.d/webapp_zic.cinay.eu_.conf</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nano /etc/nginx/conf.d/zic.cinay.eu.d/webapp_zic.cinay.eu_.conf
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#sub_path_only rewrite ^/$ / permanent;
|
|||
|
location / {
|
|||
|
# Proxy zic server
|
|||
|
|
|||
|
proxy_set_header Host $host;
|
|||
|
proxy_set_header X-Real-IP $remote_addr;
|
|||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|||
|
# Gonic port 4747, Navidrome port 4533
|
|||
|
proxy_pass http://localhost:4533;
|
|||
|
proxy_read_timeout 120;
|
|||
|
|
|||
|
# Include SSOWAT user panel.
|
|||
|
include conf.d/yunohost_panel.conf.inc;
|
|||
|
}
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>On vérifie et on relance le serveur nginx</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nginx -t
|
|||
|
sudo systemctl reload nginx
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Accès <a href="https://zic.cinay.eu">https://zic.cinay.eu</a></p>
|
|||
|
|
|||
|
<p><strong>Gonic</strong><br />
|
|||
|
<img src="/images/gonic003.png" alt="gonic" width="400" /></p>
|
|||
|
|
|||
|
<p><strong>Navidrome</strong><br />
|
|||
|
<img src="/images/navidrome01.png" alt="navidrome" width="400" /></p>
|
|||
|
|
|||
|
<h2 id="applications">Applications</h2>
|
|||
|
|
|||
|
<h3 id="calibre-web-tech-books">Calibre Web (/tech /books)</h3>
|
|||
|
|
|||
|
<h4 id="doc-technique-cinayeutech">Doc technique (cinay.eu/tech)</h4>
|
|||
|
|
|||
|
<p>Installer l’application <strong>Calibre-web</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/calibreweb_ynh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Choose the domain where this app should be installed [cinay.eu | div.cinay.eu | gitea.cinay.eu | static.cinay.eu | wg.cinay.eu | zic.cinay.eu | yanfi.net] (default: cinay.eu):
|
|||
|
Choose the path where this app should be installed (default: /calibre): /tech
|
|||
|
Choose an administrator user for this app [yann | claudine | yanfi] (default: yann):
|
|||
|
Should this app be exposed to anonymous visitors? [yes | no] (default: no):
|
|||
|
Select a default language [fr | en | es | de] (default: fr):
|
|||
|
Do you want to allow uploading of books? [yes | no] (default: no):
|
|||
|
Do you want to allow access to the library to all Yunohost users? [yes | no] (default: yes):
|
|||
|
[...]
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Emplacement par défaut de la base de donnée Calibre : <strong>/home/yunohost.multimedia/share/eBook/</strong></p>
|
|||
|
|
|||
|
<p>Ouvrir l’application https://cinay.eu/tech et basculer en administration <br />
|
|||
|
Editer la <strong>Configuration principale</strong> , modifier le dossier bibliothèque <code class="language-plaintext highlighter-rouge">/opt/sshfs/CalibreTechnique</code></p>
|
|||
|
|
|||
|
<p><img src="/images/cinay.eu-calibre.png" alt="" width="600" /></p>
|
|||
|
|
|||
|
<p>Changer le nom de l’application calibre-web</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label calibreweb 'Documentation Technique'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Accès documentation technique <a href="https://cinay.eu/tech">https://cinay.eu/tech</a></p>
|
|||
|
|
|||
|
<h4 id="livres-et-romans-cinayeubooks">Livres et romans (cinay.eu/books)</h4>
|
|||
|
|
|||
|
<p>Installer l’application <strong>Calibre-web</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://github.com/YunoHost-Apps/calibreweb_ynh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
|
|||
|
Choose a path for Calibre-web (default: /calibre): /books
|
|||
|
[...]
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Emplacement par défaut de la base de donnée Calibre : <strong>/home/yunohost.multimedia/share/eBook/</strong></p>
|
|||
|
|
|||
|
<p>Ouvrir l’application https://cinay.eu/books et basculer en administration <br />
|
|||
|
Editer la <strong>Configuration principale</strong> , dossier bibliothèque : <code class="language-plaintext highlighter-rouge">/opt/sshfs/BiblioCalibre</code> <br />
|
|||
|
Changer le nom de l’application calibre-web</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label calibreweb__2 'Livres et romans'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Accès documentation ‘Livres et romans’ <a href="https://cinay.eu/books">https://cinay.eu/books</a></p>
|
|||
|
|
|||
|
<h3 id="shaarli-cinayeushaarli">Shaarli (cinay.eu/shaarli)</h3>
|
|||
|
|
|||
|
<p><img src="/images/shaarli_logo.png" alt="image" width="50px" /><br />
|
|||
|
<em>Shaarli est un logiciel libre permettant de sauvegarder, trier, synchroniser et partager des adresses web.</em></p>
|
|||
|
|
|||
|
<p>Installation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install shaarli
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Available domains:
|
|||
|
- cinay.eu
|
|||
|
- wg.cinay.eu
|
|||
|
- zic.cinay.eu
|
|||
|
- searx.cinay.eu
|
|||
|
Choose a domain for your Shaarli (default: cinay.eu):
|
|||
|
Choose a path for your Shaarli (default: /shaarli):
|
|||
|
Is it a public Shaarli site ? [yes | no] (default: no): yes
|
|||
|
Info: Installing the app 'shaarli'…
|
|||
|
Info: Validating installation parameters...
|
|||
|
Info: Storing installation settings...
|
|||
|
Info: Installing dependencies...
|
|||
|
Info: Setting up source files...
|
|||
|
Info: Configuring nginx web server...
|
|||
|
Info: Configuring system user...
|
|||
|
Info: Configuring php-fpm...
|
|||
|
Info: Configuring log rotation...
|
|||
|
Info: Set permissions...
|
|||
|
Info: Set rights...
|
|||
|
Warning: Too many arguments ! "1" will be ignored.
|
|||
|
Info: Add Fail2Ban configuration...
|
|||
|
Warning: Too many arguments ! "1" will be ignored.
|
|||
|
Info: Configuring SSOwat...
|
|||
|
Warning: /!\ Packagers! This app is still using the skipped/protected/unprotected_uris/regex settings which are now obsolete and deprecated... Instead, you should use the new helpers 'ynh_permission_{create,urls,update,delete}' and the 'visitors' group to initialize the public/private access. Check out the documentation at the bottom of yunohost.org/groups_and_permissions to learn how to use the new permission mechanism.
|
|||
|
Info: Reloading nginx web server...
|
|||
|
Info: Installation of shaarli completed
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>liens publiques cinay.eu/shaarli <a href="https://cinay.eu/shaarli/?do=tagcloud">https://cinay.eu/shaarli/?do=tagcloud</a></p>
|
|||
|
|
|||
|
<p>Ajout signet (cinay.eu/shaarli)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>javascript:(function(){
|
|||
|
var%20url%20=%20location.href;
|
|||
|
var%20title%20=%20document.title%20||%20url;
|
|||
|
var%20desc=document.getSelection().toString();
|
|||
|
if(desc.length>4000){
|
|||
|
desc=desc.substr(0,4000)+'...';
|
|||
|
alert('Le%20texte%20s%C3%A9lectionn%C3%A9%20est%20trop%20long,%20il%20sera%20tronqu%C3%A9.');
|
|||
|
}
|
|||
|
window.open('https://cinay.eu/shaarli/?post='%20+%20encodeURIComponent(url)+ '&title='%20+%20encodeURIComponent(title)+ '&description='%20+%20encodeURIComponent(desc)+ '&source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1');
|
|||
|
})();
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="tiny-tiny-rss-ttrss">Tiny Tiny RSS (/ttrss)</h3>
|
|||
|
|
|||
|
<p><img src="/images/ttrss-logo.png" alt="image" width="50px" /><br />
|
|||
|
<em>Tiny Tiny RSS (ttrss) est un agrégateur de flux RSS et Atom libre sous licence libre GNU GPL v3</em></p>
|
|||
|
|
|||
|
<p>Installation en mode de commande (su)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install ttrss
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Available domains:
|
|||
|
- cinay.eu
|
|||
|
- yanfi.net
|
|||
|
- wg.cinay.eu
|
|||
|
- zic.cinay.eu
|
|||
|
- searx.cinay.eu
|
|||
|
Choose a domain for Tiny-Tiny-RSS (default: cinay.eu):
|
|||
|
Choose a path for Tiny-Tiny-RSS (default: /ttrss):
|
|||
|
Info: Installing the app 'ttrss'…
|
|||
|
Info: [....................] > Validating installation parameters...
|
|||
|
Info: [+...................] > Storing installation settings...
|
|||
|
Info: [#++++...............] > Installing dependencies...
|
|||
|
Info: [#####+..............] > Creating a MySQL database...
|
|||
|
Info: [######++++..........] > Setting up source files...
|
|||
|
Info: [##########..........] > Configuring nginx web server...
|
|||
|
Info: [##########+.........] > Configuring system user...
|
|||
|
Info: [###########+........] > Configuring php-fpm...
|
|||
|
Info: [############+.......] > Configuring ttrss...
|
|||
|
Info: [#############+......] > Configuring a systemd service...
|
|||
|
Info: [##############+++...] > Initializing database...
|
|||
|
Info: [#################...] > Starting ttrss...
|
|||
|
Info: [#################+..] > Configuring SSOwat...
|
|||
|
Warning: /!\ Packagers! This app is still using the skipped/protected/unprotected_uris/regex settings which are now obsolete and deprecated... Instead, you should use the new helpers 'ynh_permission_{create,urls,update,delete}' and the 'visitors' group to initialize the public/private access. Check out the documentation at the bottom of yunohost.org/groups_and_permissions to learn how to use the new permission mechanism.
|
|||
|
Info: [##################+.] > Reloading nginx web server...
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Mise à jour</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app upgrade ttrss -u https://github.com/YunoHost-Apps/ttrss_ynh/tree/testing --debug
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="nextcloud-nextcloud">Nextcloud (/nextcloud)</h3>
|
|||
|
|
|||
|
<p><img src="/images/nextcloud_logo.png" alt="" width="70" /></p>
|
|||
|
|
|||
|
<h4 id="installation-2">Installation</h4>
|
|||
|
|
|||
|
<p>en ligne de commande</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install nextcloud
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Available domains:
|
|||
|
- cinay.eu
|
|||
|
- yanfi.net
|
|||
|
- wg.cinay.eu
|
|||
|
- zic.cinay.eu
|
|||
|
- searx.cinay.eu
|
|||
|
Choose a domain for Nextcloud (default: cinay.eu):
|
|||
|
Choose a path for Nextcloud (default: /nextcloud):
|
|||
|
Available users:
|
|||
|
- yann
|
|||
|
- claudine
|
|||
|
- yanfi
|
|||
|
Choose the Nextcloud administrator (must be an existing YunoHost user): yann
|
|||
|
Access the users home folder from Nextcloud? [yes | no] (default: no): yes
|
|||
|
Info: Installing the app 'nextcloud'…
|
|||
|
Info: [....................] > Validating installation parameters...
|
|||
|
Info: [....................] > Storing installation settings...
|
|||
|
Info: [+...................] > Installing dependencies...
|
|||
|
Warning:
|
|||
|
Warning: Creating config file /etc/samba/smb.conf with new version
|
|||
|
Warning: Created symlink /etc/systemd/system/multi-user.target.wants/atd.service -> /lib/systemd/system/atd.service.
|
|||
|
Warning: Load smb config files from /etc/samba/smb.conf
|
|||
|
Warning: Loaded services file OK.
|
|||
|
Warning: Server role: ROLE_STANDALONE
|
|||
|
Warning:
|
|||
|
Info: [#+..................] > Creating a MySQL database...
|
|||
|
Info: [##..................] > Setting up source files...
|
|||
|
Info: [##..................] > Configuring nginx web server...
|
|||
|
Info: [##+.................] > Configuring system user...
|
|||
|
Info: [###++++++++.........] > Configuring php-fpm...
|
|||
|
Warning:
|
|||
|
Warning: Creating config file /etc/php/7.3/mods-available/bz2.ini with new version
|
|||
|
Warning:
|
|||
|
Warning: Creating config file /etc/php/7.3/mods-available/gmp.ini with new version
|
|||
|
Warning:
|
|||
|
Warning: Creating config file /etc/php/7.3/mods-available/zip.ini with new version
|
|||
|
Warning:
|
|||
|
Warning: Creating config file /etc/php/7.3/mods-available/imap.ini with new version
|
|||
|
Info: [###########++++.....] > Installing nextcloud...
|
|||
|
Info: [###############++...] > Configuring nextcloud...
|
|||
|
Warning: warning: commands will be executed using /bin/sh
|
|||
|
Warning: job 1 at Tue Jul 21 16:00:00 2020
|
|||
|
Warning: 2020-07-21 15:51:00 URL:https://codeload.github.com/YunoHost-Apps/yunohost.multimedia/tar.gz/v1.2 [15921] -> "v1.2.tar.gz" [1]
|
|||
|
Info: [#################+..] > Adding multimedia directories...
|
|||
|
Info: [##################..] > Configuring log rotation...
|
|||
|
Info: [##################+.] > Configuring fail2ban...
|
|||
|
Info: The service fail2ban has correctly executed the action reload-or-restart.
|
|||
|
Info: [###################.] > Configuring SSOwat...
|
|||
|
Warning: /!\ Packagers! This app is still using the skipped/protected/unprotected_uris/regex settings which are now obsolete and deprecated... Instead, you should use the new helpers 'ynh_permission_{create,urls,update,delete}' and the 'visitors' group to initialize the public/private access. Check out the documentation at the bottom of yunohost.org/groups_and_permissions to learn how to use the new permission mechanism.
|
|||
|
Warning: /!\ Packagers! This app is still using the skipped/protected/unprotected_uris/regex settings which are now obsolete and deprecated... Instead, you should use the new helpers 'ynh_permission_{create,urls,update,delete}' and the 'visitors' group to initialize the public/private access. Check out the documentation at the bottom of yunohost.org/groups_and_permissions to learn how to use the new permission mechanism.
|
|||
|
Info: [###################.] > Reloading nginx web server...
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Dans les paramètres fichier de nextcloud , activer l’affichage des fichiers masqués</p>
|
|||
|
|
|||
|
<h4 id="activer-les-applications">Activer les applications</h4>
|
|||
|
|
|||
|
<p>Activer les applications <strong>Calendar</strong>, <strong>Contacts</strong> et <strong>Notes</strong> sur nextcloud</p>
|
|||
|
|
|||
|
<h4 id="calendrier-et-contacts-android-et-thunderbird">Calendrier et contacts (android et thunderbird)</h4>
|
|||
|
|
|||
|
<p>Paramétrage <strong>OpenSync</strong> android<br />
|
|||
|
Connexion avec le lien https://cinay.eu/nextcloud/remote.php/dav (login+mdp)<br />
|
|||
|
<img src="/images/opensync-1.png" alt="" height="300" /> <img src="/images/opensync-2.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Paramétrer les applications qui utilisent le calendrier et les contacts<br />
|
|||
|
<strong>Contacts</strong> , <strong>acalendar</strong> et <strong>Tâches</strong><br />
|
|||
|
<img src="/images/opensync-3.png" alt="" height="300" /> <img src="/images/opensync-4.png" alt="" height="300" /> <img src="/images/opensync-5.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Paramétrage agenda <strong>Thunderbird</strong><br />
|
|||
|
<img src="/images/thb001.png" alt="" width="300" /> <img src="/images/thb002.png" alt="" width="300" /><br />
|
|||
|
<img src="/images/thb003.png" alt="" width="300" /> <img src="/images/thb004.png" alt="" width="300" />
|
|||
|
<img src="/images/thb005.png" alt="" width="300" /><br />
|
|||
|
Se désabonner de l’ancien agenda cinay.xyz</p>
|
|||
|
|
|||
|
<p>Paramétrage contacts <strong>Thunderbird</strong><br />
|
|||
|
Outils → Préférences des modules → TbSync <br />
|
|||
|
Dans l’application<br />
|
|||
|
Actions sur les comptes → Ajouter un nouveau compte → Caldav & Carddav<br />
|
|||
|
<img src="/images/tbsync01.png" alt="" width="300" /> <img src="/images/tbsync02.png" alt="" width="300" /> <br />
|
|||
|
<img src="/images/tbsync03.png" alt="" width="300" /> <br />
|
|||
|
<img src="/images/tbsync04.png" alt="" width="300" /> <br />
|
|||
|
Synchronisation toutes les heures pour les contacts</p>
|
|||
|
|
|||
|
<p>Liens caldav carddav sur thunderbird (yann) <br />
|
|||
|
https://cinay.eu/nextcloud/remote.php/dav/calendars/yann/personal/<br />
|
|||
|
https://cinay.eu/nextcloud/remote.php/dav/addressbooks/users/yann/contacts/</p>
|
|||
|
|
|||
|
<h4 id="compte-nextcloud-sur-les-postes-clients-de-type-pc">Compte nextcloud sur les postes clients de type PC</h4>
|
|||
|
|
|||
|
<p>Ajout du compte https://cinay.eu/nextcloud sur les clients nextcloud <br />
|
|||
|
Synchronisations:</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li>~/.keepassx → Home/.keepassx (créer le dossier)</li>
|
|||
|
<li>~/media/Notes → Notes (créer le dossier)</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<h4 id="compte-nextcloud-sur-android">Compte nextcloud sur android</h4>
|
|||
|
|
|||
|
<p>Application nextcloud installée<br />
|
|||
|
Se connecter https://cinay.eu/nextcloud et vérifier la création du compte<br />
|
|||
|
<img src="/images/ncinayeu001.png" alt="" height="300" /></p>
|
|||
|
|
|||
|
<p>Synchroniser le fichier de mot de passe avec l’application keepass<br />
|
|||
|
<img src="/images/ncinayeu002.png" alt="" height="300" /> <img src="/images/ncinayeu003.png" alt="" height="300" /><br />
|
|||
|
<img src="/images/ncinayeu004.png" alt="" width="200" /></p>
|
|||
|
|
|||
|
<h3 id="gitea-giteacinayeu">Gitea (gitea.cinay.eu)</h3>
|
|||
|
|
|||
|
<p><img src="/images/gitea-logo.png" alt="" width="70" /></p>
|
|||
|
|
|||
|
<p>Ajout domaine et certificats gitea.cinay.eu</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add gitea.cinay.eu
|
|||
|
yunohost domain cert-install gitea.cinay.eu --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installation à partir de github, on clône le dépôt</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/YunoHost-Apps/gitea_ynh.git
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Blocage sur fail2ban à l’installation <br />
|
|||
|
Commenter la mise en place FAIL2BAN</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano gitea_ynh/scripts/install
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># SETUP FAIL2BAN
|
|||
|
#ynh_script_progression --message="Configuring fail2ban..."
|
|||
|
#ynh_add_fail2ban_config --logpath "/var/log/$app/gitea.log" --failregex ".*Failed authentication attempt for .* from <HOST>" --max_retry 5
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer gitea</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install gitea_ynh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Fail2ban , règle qui n’est pas ajouté</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ynh_add_fail2ban_config --logpath /var/log/gitea/gitea.log --failregex '.*Failed authentication attempt for .* from <HOST>' --max_retry 5
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Probème de mise à jour</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app upgrade gitea -u https://github.com/YunoHost-Apps/gitea_ynh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Warning: Reload the service fail2ban
|
|||
|
Warning: ............................................................................................................................................................................................................................................................................................................The service fail2ban didn't fully started before the timeout.
|
|||
|
Warning: -- Logs begin at Thu 2020-10-08 17:30:01 CEST, end at Fri 2020-10-09 11:17:21 CEST. --
|
|||
|
Warning: Oct 09 10:21:56 cinay.eu fail2ban-client[26484]: OK
|
|||
|
Warning: Oct 09 10:21:56 cinay.eu systemd[1]: Reloaded Fail2Ban Service.
|
|||
|
Warning: Oct 09 10:28:15 cinay.eu systemd[1]: Reloading Fail2Ban Service.
|
|||
|
Warning: Oct 09 10:28:15 cinay.eu fail2ban-client[27234]: OK
|
|||
|
Warning: Oct 09 10:28:15 cinay.eu systemd[1]: Reloaded Fail2Ban Service.
|
|||
|
Warning: Oct 09 10:52:39 cinay.eu systemd[1]: /lib/systemd/system/fail2ban.service:12: PIDFile= references path below legacy directory /var/run/, updating /var/run/fail2ban/fail2ban.pid → /run/fail2ban/fail2ban.pid; please update the unit file accordingly.
|
|||
|
Warning: Oct 09 10:52:40 cinay.eu systemd[1]: /lib/systemd/system/fail2ban.service:12: PIDFile= references path below legacy directory /var/run/, updating /var/run/fail2ban/fail2ban.pid → /run/fail2ban/fail2ban.pid; please update the unit file accordingly.
|
|||
|
Warning: Oct 09 10:52:57 cinay.eu systemd[1]: Reloading Fail2Ban Service.
|
|||
|
Warning: Oct 09 10:52:57 cinay.eu fail2ban-client[32448]: OK
|
|||
|
Warning: Oct 09 10:52:57 cinay.eu systemd[1]: Reloaded Fail2Ban Service.
|
|||
|
Warning: Oct 09 10:57:21 cinay.eu systemd[1]: /lib/systemd/system/fail2ban.service:12: PIDFile= references path below legacy directory /var/run/, updating /var/run/fail2ban/fail2ban.pid → /run/fail2ban/fail2ban.pid; please update the unit file accordingly.
|
|||
|
Warning: Oct 09 10:57:22 cinay.eu systemd[1]: /lib/systemd/system/fail2ban.service:12: PIDFile= references path below legacy directory /var/run/, updating /var/run/fail2ban/fail2ban.pid → /run/fail2ban/fail2ban.pid; please update the unit file accordingly.
|
|||
|
Warning: Oct 09 10:57:36 cinay.eu systemd[1]: Reloading Fail2Ban Service.
|
|||
|
Warning: Oct 09 10:57:36 cinay.eu fail2ban-client[5219]: OK
|
|||
|
Warning: Oct 09 10:57:36 cinay.eu systemd[1]: Reloaded Fail2Ban Service.
|
|||
|
Warning: Oct 09 11:12:33 cinay.eu systemd[1]: /lib/systemd/system/fail2ban.service:12: PIDFile= references path below legacy directory /var/run/, updating /var/run/fail2ban/fail2ban.pid → /run/fail2ban/fail2ban.pid; please update the unit file accordingly.
|
|||
|
Warning: Oct 09 11:12:33 cinay.eu systemd[1]: /lib/systemd/system/fail2ban.service:12: PIDFile= references path below legacy directory /var/run/, updating /var/run/fail2ban/fail2ban.pid → /run/fail2ban/fail2ban.pid; please update the unit file accordingly.
|
|||
|
Warning: Oct 09 11:12:48 cinay.eu systemd[1]: Reloading Fail2Ban Service.
|
|||
|
Warning: Oct 09 11:12:48 cinay.eu fail2ban-client[10435]: OK
|
|||
|
Warning: Oct 09 11:12:48 cinay.eu systemd[1]: Reloaded Fail2Ban Service.
|
|||
|
Info: [###############.....] > Update permission...
|
|||
|
Warning: Group 'visitors' already has permission 'gitea.main' enabled
|
|||
|
Warning: This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.
|
|||
|
Warning: The permission was not updated because the addition/removal requests already match the current state.
|
|||
|
Warning: /usr/share/yunohost/helpers.d/utils: line 583: manifest: unbound variable
|
|||
|
Info: [###############+....] > Protecting directory
|
|||
|
Info: [################+...] > Configuring permissions...
|
|||
|
Warning: Group 'visitors' already has permission 'gitea.main' enabled
|
|||
|
Warning: This permission is currently granted to all users in addition to other groups. You probably want to either remove the 'all_users' permission or remove the other groups it is currently granted to.
|
|||
|
Warning: The permission was not updated because the addition/removal requests already match the current state.
|
|||
|
Warning: Start the service gitea
|
|||
|
Info: [#################++.] > Starting gitea services...
|
|||
|
Warning: ..The service gitea has correctly started.
|
|||
|
sh: 0: getcwd() failed: No such file or directory
|
|||
|
sh: 0: getcwd() failed: No such file or directory
|
|||
|
Success! gitea upgraded
|
|||
|
sh: 0: getcwd() failed: No such file or directory
|
|||
|
sh: 0: getcwd() failed: No such file or directory
|
|||
|
sh: 0: getcwd() failed: No such file or directory
|
|||
|
Success! Upgrade complete
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Redémarrer fail2ban</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart fail2ban
|
|||
|
journalctl --unit=fail2ban
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Oct 09 11:27:39 cinay.eu systemd[1]: Stopping Fail2Ban Service...
|
|||
|
Oct 09 11:27:40 cinay.eu fail2ban-client[12316]: Shutdown successful
|
|||
|
Oct 09 11:27:40 cinay.eu systemd[1]: fail2ban.service: Main process exited, code=killed, status=15/TERM
|
|||
|
Oct 09 11:27:40 cinay.eu systemd[1]: fail2ban.service: Succeeded.
|
|||
|
Oct 09 11:27:40 cinay.eu systemd[1]: Stopped Fail2Ban Service.
|
|||
|
Oct 09 11:27:40 cinay.eu systemd[1]: Starting Fail2Ban Service...
|
|||
|
Oct 09 11:27:40 cinay.eu systemd[1]: Started Fail2Ban Service.
|
|||
|
Oct 09 11:27:40 cinay.eu fail2ban-server[12320]: Server ready
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="staticcinayeu">static.cinay.eu</h3>
|
|||
|
|
|||
|
<p>En mode su</p>
|
|||
|
|
|||
|
<p>Créer le domaine static.cinay.eu et les certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add static.cinay.eu
|
|||
|
yunohost domain cert-install static.cinay.eu --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer l’application Multi web app sur le domaine static.cinay.eu</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://gitea.cinay.eu/yann/multi_webapp_buster_ynh
|
|||
|
yunohost app install https://gitea.cinay.eu/yann/multi_webapp_buster_ynh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>DANGER! This app is not part of Yunohost's app catalog. Installing third-party apps may compromise the integrity and security of your system. You should probably NOT install it unless you know what you are doing. NO SUPPORT will be provided if this app doesn't work or breaks your system… If you are willing to take that risk anyway, type 'Yes, I understand': Yes, I understand
|
|||
|
Available domains:
|
|||
|
- cinay.eu
|
|||
|
- yanfi.net
|
|||
|
- wg.cinay.eu
|
|||
|
- zic.cinay.eu
|
|||
|
- static.cinay.eu
|
|||
|
- gitea.cinay.eu
|
|||
|
- searx.cinay.eu
|
|||
|
Choose a domain for your Webapp (default: cinay.eu): static.cinay.eu
|
|||
|
Choose a path for your Webapp (default: /site): /
|
|||
|
Available users:
|
|||
|
- yann
|
|||
|
- claudine
|
|||
|
- yanfi
|
|||
|
Choose the YunoHost user: yann
|
|||
|
Create a database? [yes | no] (default: no):
|
|||
|
Is it a public website ? [yes | no] (default: no): yes
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><code class="language-plaintext highlighter-rouge">multi_webapp__3</code> (static.cinay.eu) à un accès complet sans aucune autorisation</p>
|
|||
|
|
|||
|
<p>Le dossier <strong>/opt/yann/static/</strong> contient le site statique qui est issu d’une synchronisation d’un conteneur debian sur un ordinateur archlinux avec jekyll comme générateur</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">rm</span> <span class="nt">-r</span> /var/www/webapp_yann/static.cinay.eu_ <span class="c"># supprimer dossier web </span>
|
|||
|
<span class="nb">ln</span> <span class="nt">-s</span> /opt/yann/static /var/www/webapp_yann/static.cinay.eu_ <span class="c"># lien</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier l’étiquette <code class="language-plaintext highlighter-rouge">multi_webapp__3</code> (static.cinay.eu)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label multi_webapp__3 'Statique static.cinay.eu'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="divcinayeu">div.cinay.eu</h3>
|
|||
|
|
|||
|
<p>En mode su</p>
|
|||
|
|
|||
|
<p>Créer le domaine div.cinay.eu et les certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost domain add div.cinay.eu
|
|||
|
yunohost domain cert-install div.cinay.eu --no-checks
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer l’application Multi web app sur le domaine div.cinay.eu</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://gitea.cinay.eu/yann/multi_webapp_buster_ynh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
|
|||
|
Choose a domain for your Webapp (default: cinay.eu): div.cinay.eu
|
|||
|
Choose a path for your Webapp (default: /site): /
|
|||
|
Available users:
|
|||
|
- yann
|
|||
|
- claudine
|
|||
|
- yanfi
|
|||
|
Choose the YunoHost user: yann
|
|||
|
Create a database? [yes | no] (default: no):
|
|||
|
Is it a public website ? [yes | no] (default: no): yes
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier l’étiquette <code class="language-plaintext highlighter-rouge">multi_webapp__4</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label multi_webapp__4 'div.cinay.eu'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le dossier correspondant : <code class="language-plaintext highlighter-rouge">/var/www/webapp_yann/div.cinay.eu_/</code><br />
|
|||
|
Créer des liens</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo ln -s /opt/sshfs/diceware /var/www/webapp_yann/div.cinay.eu_/diceware
|
|||
|
sudo ln -s /opt/sshfs/osm-new /var/www/webapp_yann/div.cinay.eu_/osm-new
|
|||
|
sudo ln -s /opt/sshfs/htmldoc /var/www/webapp_yann/div.cinay.eu_/htmldoc
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le site</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ls -la /var/www/webapp_yann/div.cinay.eu_/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>total 24
|
|||
|
drwxrwxr-x 4 yann webapp_div.cinay.eu_ 4096 Sep 23 15:55 <span class="nb">.</span>
|
|||
|
drwxr-xr-x 5 root root 4096 Sep 23 12:02 ..
|
|||
|
drwxr-xr-x 6 debian debian 4096 Jun 6 2019 assets
|
|||
|
lrwxrwxrwx 1 root root 19 Sep 23 15:55 diceware -> /opt/sshfs/diceware
|
|||
|
drwxr-xr-x 4 debian debian 4096 Sep 23 14:17 images
|
|||
|
<span class="nt">-rw-r--r--</span> 1 debian debian 6922 Sep 23 15:49 index.html
|
|||
|
lrwxrwxrwx 1 root root 18 Sep 23 15:55 osm-new -> /opt/sshfs/osm-new
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="cinayeusite-cartes">cinay.eu/site (cartes)</h3>
|
|||
|
|
|||
|
<p>Installer l’application Multi web app</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app install https://gitea.cinay.eu/yann/multi_webapp_buster_ynh
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[...]
|
|||
|
Choose the domain where this app should be installed [cinay.eu | div.cinay.eu | gitea.cinay.eu | static.cinay.eu | wg.cinay.eu | zic.cinay.eu | yanfi.net] (default: cinay.eu):
|
|||
|
Choose the path where this app should be installed (default: /site):
|
|||
|
Choose an administrator user for this app [yann | claudine | yanfi] (default: yann):
|
|||
|
Create a database? [yes | no] (default: no):
|
|||
|
Should this app be exposed to anonymous visitors? [yes | no] (default: no): yes
|
|||
|
[...]
|
|||
|
Success! Installation completed
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier l’étiquette <code class="language-plaintext highlighter-rouge">multi_webapp__5</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yunohost app change-label multi_webapp__5 '/site Cartes '
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le dossier correspondant : <code class="language-plaintext highlighter-rouge">/var/www/webapp_yann/cinay.eu_site/</code><br />
|
|||
|
Le lien</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm -r /var/www/webapp_yann/cinay.eu_site
|
|||
|
sudo ln -s /opt/sshfs/osm-new /var/www/webapp_yann/cinay.eu_site
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="sauvegardes">Sauvegardes</h2>
|
|||
|
|
|||
|
<h4 id="yunohost-1">yunohost</h4>
|
|||
|
|
|||
|
<p>Création d’une sauvegarde complète yunohost</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
yunohost backup create -n Backup-Yunohost-cinay.eu
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Sauvegarde automatique tous les jours</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
crontab -e
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Sauvegarde yunohost
|
|||
|
00 02 * * * /usr/bin/rm /home/yunohost.backup/archives/* && /usr/bin/yunohost backup create -n Backup-Yunohost-cinay.eu > /dev/null
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="borgbackup">BorgBackup</h4>
|
|||
|
|
|||
|
<p><img src="/images/borg-logo.png" alt="" /></p>
|
|||
|
|
|||
|
<p><strong>Préparation de la machine à sauvegarder</strong><br />
|
|||
|
On se connecte sur la machine et on passe en mode su</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
apt update
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installer borgbackup</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install borgbackup
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong><u>Créer un jeu de clé sur machine à sauvegarder (cinay.eu)</u></strong><br />
|
|||
|
Créer un utilisateur borg (sans home) dédié aux sauvegardes par BorgBackup :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>useradd -M borg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Générer un jeu de clé sur <strong>/root/.ssh</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p /root/.ssh
|
|||
|
ssh-keygen -t ed25519 -o -a 100 -f /root/.ssh/cinay.eu_ed25519
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le jeu de clé</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ls /root/.ssh
|
|||
|
cinay.eu_ed25519 cinay.eu_ed25519.pub
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Autoriser utilisateur <strong>borg</strong> à exécuter <em>/usr/bin/borg</em> uniquement</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "borg ALL=NOPASSWD: /usr/bin/borg" >> /etc/sudoers
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Ajout clé publique au serveur backup xoyaz.xyz</strong></p>
|
|||
|
|
|||
|
<blockquote>
|
|||
|
<p>Pour une connexion via ssh vous devez ajouter la clé publique <em>cinay.eu_ed25519.pub</em> du <strong>serveur client cinay.eu</strong> au fichier <em>~/.ssh/authorized_keys</em> du <strong>serveur backup xoyaz.xyz</strong></p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<p>Se connecter au <strong>serveur backup xoyaz.xyz</strong> depuis un terminal autorisé</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh usernl@5.2.79.107 -p 55036 -i /home/yannick/.ssh/OVZ-STORAGE-128 # connexion SSH serveur backup depuis PC1
|
|||
|
sudo -s # passer en super utilisateur
|
|||
|
cat >> /srv/data/borg-backups/.ssh/authorized_keys
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Copier/coller le contenu du fichier du fichier de clef publique (fichier <strong>/root/.ssh/cinay.eu_ed25519.pub</strong> de la machine à sauvegarder <strong>cinay.eu</strong> ) dans ce terminal, et presser <strong>[Ctrl]+[D]</strong> pour valider.</p>
|
|||
|
|
|||
|
<p>Test depuis le serveur client <strong>cinay.eu</strong> (c’est lui qui possède la clé privée).<br />
|
|||
|
<em>Si parefeu avec les sorties bloquées sur <strong>cinay.eu</strong> , il faut ouvrir en sortie le port TCP 55036.</em></p>
|
|||
|
|
|||
|
<p><strong>AU PREMIER passage une question est posée , saisir oui ou yes</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
ssh -p 55036 -i /root/.ssh/cinay.eu_ed25519 borg@xoyaz.xyz
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The authenticity of host '[xoyaz.xyz]:55036 ([2a04:52c0:101:7ae::7a5e]:55036)' can't be established.
|
|||
|
ECDSA key fingerprint is SHA256:PDXQBhTh4oj0cSzgnjCun+J60JDUEk7VeLH2YHZbwMc.
|
|||
|
Are you sure you want to continue connecting (yes/no)? yes
|
|||
|
hosts.
|
|||
|
Linux vps70253415 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64
|
|||
|
____ __ ___ ___ ____ _ _ _ ___
|
|||
|
__ __ _ __ ___|__ |/ \|_ )| __||__ /| | | / || __|
|
|||
|
\ V /| '_ \(_-< / /| () |/ / |__ \ |_ \|_ _|| ||__ \
|
|||
|
\_/ | .__//__/ /_/ \__//___||___/|___/ |_| |_||___/
|
|||
|
__|_| ___ ____ ___ _ ___ ____
|
|||
|
| __| |_ ) |__ |/ _ \ / ||_ )|__ |
|
|||
|
|__ \ _ / / _ / / \_, /_ | | / / / /
|
|||
|
|___/(_)/___|(_)/_/ /_/(_)|_|/___| /_/
|
|||
|
Last login: Wed Jun 10 15:34:07 2020 from 51.91.249.57
|
|||
|
$
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>saisir <code class="language-plaintext highlighter-rouge">exit</code> pour sortir</p>
|
|||
|
|
|||
|
<blockquote>
|
|||
|
<p>NOTE : <strong>/srv/data/borg-backups</strong> est le home de l’utilisateur <em>borg</em> sur le serveur backup <em>xoyaz.xyz</em></p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<p><strong>Création dépôt et lancement des sauvegardes depuis la machine à sauvegarder</strong></p>
|
|||
|
|
|||
|
<p><strong><u>machine cliente cinay.eu</u></strong><br />
|
|||
|
On se connecte sur la machine et on passe en mode su</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Création du dépôt distant sur le serveur backup xoyaz.xyz (A FAIRE UNE SEULE FOIS)</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>export BORG_RSH='ssh -i /root/.ssh/cinay.eu_ed25519' # ce n'est pas la clé par défaut id_rsa
|
|||
|
borg init --encryption=repokey-blake2 ssh://borg@xoyaz.xyz:55036/srv/data/borg-backups/cinay.eu
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Enter new passphrase:
|
|||
|
Enter same passphrase again:
|
|||
|
Do you want your passphrase to be displayed for verification? [yN]:
|
|||
|
|
|||
|
By default repositories initialized with this version will produce security
|
|||
|
errors if written to with an older version (up to and including Borg 1.0.8).
|
|||
|
|
|||
|
If you want to use these older versions, you can disable the check by running:
|
|||
|
borg upgrade --disable-tam ssh://borg@xoyaz.xyz:55036/srv/data/borg-backups/cinay.eu
|
|||
|
|
|||
|
See https://borgbackup.readthedocs.io/en/stable/changes.html#pre-1-0-9-manifest-spoofing-vulnerability for details about the security implications.
|
|||
|
|
|||
|
IMPORTANT: you will need both KEY AND PASSPHRASE to access this repo!
|
|||
|
Use "borg key export" to export the key, optionally in printable format.
|
|||
|
Write down the passphrase. Store both at safe place(s).
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Sauvegarder la “passphrase” dans un fichier pour une procédure automatique</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p /root/.borg
|
|||
|
nano /root/.borg/passphrase
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Générer une sauvegarde d’un dossier local vers le dépôt distant</strong> pour test (facultatif)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>borg create ssh://borg@xoyize.xyz:55029/srv/ssd-two/borg-backups/cinay.eu::2019-01-11 /home/yanfi
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Enter passphrase for key ssh://borg@xoyize.xyz:55029/srv/ssd-two/borg-backups/cinay.eu:
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Automatiser la procédure de sauvegarde pour le client cinay.eu</strong><br />
|
|||
|
script de sauvegarde (notez l’usage de borg prune pour supprimer les archives trop anciennes)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /root/.borg/borg-backup
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/sh
|
|||
|
#
|
|||
|
# Script de sauvegarde.
|
|||
|
#
|
|||
|
# Envoie les sauvegardes sur un serveur distant, via le programme Borg.
|
|||
|
# Les sauvegardes sont chiffrées
|
|||
|
#
|
|||
|
|
|||
|
set -e
|
|||
|
|
|||
|
BACKUP_DATE=`date +%Y-%m-%d-%Hh%M`
|
|||
|
LOG_PATH=/var/log/borg-backup.log
|
|||
|
|
|||
|
export BORG_PASSPHRASE="`cat ~root/.borg/passphrase`"
|
|||
|
export BORG_RSH='ssh -i /root/.ssh/cinay.eu_ed25519'
|
|||
|
BORG_REPOSITORY=ssh://borg@xoyaz.xyz:55036/srv/data/borg-backups/cinay.eu
|
|||
|
BORG_ARCHIVE=${BORG_REPOSITORY}::${BACKUP_DATE}
|
|||
|
|
|||
|
borg create \
|
|||
|
-v --progress --stats --compression lzma,9 \
|
|||
|
--exclude-from /root/.borg/exclusions --exclude-caches \
|
|||
|
$BORG_ARCHIVE \
|
|||
|
/ \
|
|||
|
>> ${LOG_PATH} 2>&1
|
|||
|
|
|||
|
# Nettoyage des anciens backups
|
|||
|
# On conserve
|
|||
|
# - une archive par jour les 7 derniers jours,
|
|||
|
# - une archive par semaine pour les 4 dernières semaines,
|
|||
|
# - une archive par mois pour les 6 derniers mois.
|
|||
|
|
|||
|
borg prune \
|
|||
|
-v --list --stats --keep-daily=7 --keep-weekly=4 --keep-monthly=6 \
|
|||
|
$BORG_REPOSITORY \
|
|||
|
>> ${LOG_PATH} 2>&1
|
|||
|
|
|||
|
root@cinay:/home/debian# nano /root/.borg/borg-backup
|
|||
|
root@cinay:/home/debian# cat /root/.borg/borg-backup
|
|||
|
#!/bin/sh
|
|||
|
#
|
|||
|
# Script de sauvegarde.
|
|||
|
#
|
|||
|
# Envoie les sauvegardes sur un serveur distant, via le programme Borg.
|
|||
|
# Les sauvegardes sont chiffrées
|
|||
|
#
|
|||
|
|
|||
|
set -e
|
|||
|
|
|||
|
BACKUP_DATE=`date +%Y-%m-%d-%Hh%M`
|
|||
|
LOG_PATH=/var/log/borg-backup.log
|
|||
|
|
|||
|
export BORG_PASSPHRASE="`cat ~root/.borg/passphrase`"
|
|||
|
export BORG_RSH='ssh -i /root/.ssh/cinay.eu_ed25519'
|
|||
|
BORG_REPOSITORY=ssh://borg@xoyaz.xyz:55036/srv/data/borg-backups/cinay.eu
|
|||
|
BORG_ARCHIVE=${BORG_REPOSITORY}::${BACKUP_DATE}
|
|||
|
|
|||
|
borg create \
|
|||
|
-v --progress --stats --compression lzma,9 \
|
|||
|
--exclude-caches --exclude-from /root/.borg/exclusions \
|
|||
|
$BORG_ARCHIVE \
|
|||
|
/ \
|
|||
|
>> ${LOG_PATH} 2>&1
|
|||
|
|
|||
|
# Nettoyage des anciens backups
|
|||
|
# On conserve
|
|||
|
# - une archive par jour les 7 derniers jours,
|
|||
|
# - une archive par semaine pour les 4 dernières semaines,
|
|||
|
# - une archive par mois pour les 6 derniers mois.
|
|||
|
|
|||
|
borg prune \
|
|||
|
-v --list --stats --keep-daily=7 --keep-weekly=4 --keep-monthly=6 \
|
|||
|
$BORG_REPOSITORY \
|
|||
|
>> ${LOG_PATH} 2>&1
|
|||
|
|
|||
|
exit 0
|
|||
|
# Ancien backup
|
|||
|
borg create \
|
|||
|
-v --progress --stats --compression lzma,9 \
|
|||
|
--exclude-from /root/.borg/exclusions --exclude-caches \
|
|||
|
$BORG_ARCHIVE \
|
|||
|
/ \
|
|||
|
>> ${LOG_PATH} 2>&1
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le rendre exécutable</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>chmod +x /root/.borg/borg-backup
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Fichier <strong>/root/.borg/exclusions</strong> pour ne pas sauvegarder, entre autre,le point de montage ssfs “music” (si existant)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nano /root/.borg/exclusions
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/dev
|
|||
|
/proc
|
|||
|
/sys
|
|||
|
/tmp
|
|||
|
/run
|
|||
|
/mnt
|
|||
|
/media
|
|||
|
lost+found
|
|||
|
/home/yunohost.multimedia
|
|||
|
/home/yunohost.backup
|
|||
|
/home/yunohost.transmission
|
|||
|
/home/yunohost.app
|
|||
|
/opt/sshfs
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Programmer la tâche à 2h40 du matin</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>crontab -e
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Sauvegarde sur distant avec BorgBackup
|
|||
|
40 02 * * * /root/.borg/borg-backup > /dev/null
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="tests-sur-le-serveur">Tests sur le serveur</h2>
|
|||
|
|
|||
|
<h4 id="vérifications-dns---wireguard">Vérifications DNS - wireguard</h4>
|
|||
|
|
|||
|
<p>Les commandes suivantes ne fonctionneront que si le paquet “dnsutils” est installé sur votre système Debian!</p>
|
|||
|
|
|||
|
<p>On teste en utilisant les serveurs DNS locaux, les 3 commandes suivantes ont le même résultat</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dig @127.0.0.1 afnic.fr +short +dnssec
|
|||
|
dig @10.55.22.1 afnic.fr +short +dnssec
|
|||
|
dig @fd87:9aa8:e67c:5a80::1 afnic.fr +short +dnssec
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>192.134.5.37
|
|||
|
A 13 2 600 20200608204052 20200509084949 30435 afnic.fr. eVchVAseJD5n8W7U8okAz546Ix33hOCqRF7wLrhUV+sOTkwyXo7EwAut k/rN8wsPVpTnTpFyQLKdBTuOpx2UxA==
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="propagation-dns">Propagation DNS</h4>
|
|||
|
|
|||
|
<p><a href="https://www.whatsmydns.net">https://www.whatsmydns.net</a><br />
|
|||
|
<img src="/images/propagationdns-cinay.eu.png" alt="" width="400" /></p>
|
|||
|
|
|||
|
<h4 id="messagerie">Messagerie</h4>
|
|||
|
|
|||
|
<p>Vérification messagerie <a href="https://mecsa.jrc.ec.europa.eu/fr/">https://mecsa.jrc.ec.europa.eu/fr/</a><br />
|
|||
|
<img src="/images/messagerie-cinay.eu.png" alt="" width="600" /></p>
|
|||
|
|
|||
|
<h4 id="dns-blacklisting">DNS blacklisting</h4>
|
|||
|
|
|||
|
<p><a href="https://www.dnsbl.info/dnsbl-database-check.php">https://www.dnsbl.info/dnsbl-database-check.php</a><br />
|
|||
|
<img src="/images/dnsbl-cinay.eu.png" alt="" width="600" /></p>
|
|||
|
|
|||
|
<h4 id="vulnérabilités">Vulnérabilités</h4>
|
|||
|
|
|||
|
<p><a href="https://www.ssllabs.com/ssltest/analyze.html">https://www.ssllabs.com/ssltest/analyze.html</a></p>
|
|||
|
|
|||
|
<p>SSL Report: cinay.eu (164.132.104.145)<br />
|
|||
|
<img src="/images/ssllabs-cinay.eu-01.png" alt="Texte alternatif" width="500" /></p>
|
|||
|
|
|||
|
<p>SSL Report: cinay.eu (2001:41d0:401:3200:0:0:0:6e7)<br />
|
|||
|
<img src="/images/ssllabs-cinay.eu-02.png" alt="Texte alternatif" width="500" /></p>
|
|||
|
|
|||
|
<p>Vérifier les ports ouverts depuis un poste linux</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nmap 164.132.104.145
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Starting Nmap 7.70 ( https://nmap.org ) at 2020-09-25 07:34 CEST
|
|||
|
Nmap scan report for cinay.eu (164.132.104.145)
|
|||
|
Host is up (0.018s latency).
|
|||
|
Not shown: 990 filtered ports
|
|||
|
PORT STATE SERVICE
|
|||
|
25/tcp open smtp
|
|||
|
53/tcp open domain
|
|||
|
80/tcp open http
|
|||
|
443/tcp open https
|
|||
|
587/tcp open submission
|
|||
|
993/tcp open imaps
|
|||
|
5222/tcp open xmpp-client
|
|||
|
5269/tcp open xmpp-server
|
|||
|
8083/tcp open us-srv
|
|||
|
8084/tcp open unknown
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>On s’intéresse aux ports 8083 8084 , qui les utilise ?</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@cinay:/home/debian# netstat <span class="nt">-ltnpu</span> | <span class="nb">grep</span> <span class="nt">-w</span> <span class="s1">'8083'</span>
|
|||
|
tcp 0 0 0.0.0.0:8083 0.0.0.0:<span class="k">*</span> LISTEN 722/python3
|
|||
|
tcp6 0 0 :::8083 :::<span class="k">*</span> LISTEN 722/python3
|
|||
|
|
|||
|
root@cinay:/home/debian# ss <span class="nt">-lptnu</span> | <span class="nb">grep</span> <span class="nt">-w</span> <span class="s1">'8083'</span>
|
|||
|
tcp LISTEN 0 128 0.0.0.0:8083 0.0.0.0:<span class="k">*</span> <span class="nb">users</span>:<span class="o">((</span><span class="s2">"python3"</span>,pid<span class="o">=</span>722,fd<span class="o">=</span>5<span class="o">))</span>
|
|||
|
tcp LISTEN 0 128 <span class="o">[</span>::]:8083 <span class="o">[</span>::]:<span class="k">*</span> <span class="nb">users</span>:<span class="o">((</span><span class="s2">"python3"</span>,pid<span class="o">=</span>722,fd<span class="o">=</span>7<span class="o">))</span>
|
|||
|
|
|||
|
l affiche les sockets à l’écoute,
|
|||
|
t affiche les connexions tcp,
|
|||
|
u pour le protocole udp,
|
|||
|
n permet l’affichage des adresses sous forme numérique,
|
|||
|
p affiche les processus,
|
|||
|
L’option <span class="nt">-w</span> de <span class="nb">grep </span>nous affiche la meilleure correspondance de la chaîne de caractères fournie.
|
|||
|
|
|||
|
root@cinay:/home/debian# lsof <span class="nt">-i</span> :8083
|
|||
|
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
|
|||
|
python3 722 calibreweb 5u IPv4 23022 0t0 TCP <span class="k">*</span>:8083 <span class="o">(</span>LISTEN<span class="o">)</span>
|
|||
|
python3 722 calibreweb 7u IPv6 23023 0t0 TCP <span class="k">*</span>:8083 <span class="o">(</span>LISTEN<span class="o">)</span>
|
|||
|
|
|||
|
root@cinay:/home/debian# lsof <span class="nt">-i</span> :8084
|
|||
|
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
|
|||
|
python3 727 calibreweb__2 5u IPv4 23016 0t0 TCP <span class="k">*</span>:8084 <span class="o">(</span>LISTEN<span class="o">)</span>
|
|||
|
python3 727 calibreweb__2 7u IPv6 23017 0t0 TCP <span class="k">*</span>:8084 <span class="o">(</span>LISTEN<span class="o">)</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2020-11-04T00:00:00+01:00"><!-- start custom article footer snippet -->
|
|||
|
|
|||
|
<!-- end custom article footer snippet -->
|
|||
|
<!--
|
|||
|
<div align="right"><a type="application/rss+xml" href="/feed.xml" title="S'abonner"><i class="fa fa-rss fa-2x"></i></a>
|
|||
|
|
|||
|
 </div>
|
|||
|
-->
|
|||
|
</footer>
|
|||
|
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2020/10/29/Bash-commandes-utiles.html">Bash commandes utiles</a></div><div class="next"><span>SUIVANT</span><a href="/2020/11/07/VPS-Hetzner-CX11_BIS_debian_10.html">HETZNER VPS CX11 Bis debian 10 yunohost</a></div></div></div>
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
<script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
$(function() {
|
|||
|
var $this ,$scroll;
|
|||
|
var $articleContent = $('.js-article-content');
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
|
|||
|
$scroll = $(scroll);
|
|||
|
|
|||
|
$articleContent.find('.highlight').each(function() {
|
|||
|
$this = $(this);
|
|||
|
$this.attr('data-lang', $this.find('code').attr('data-lang'));
|
|||
|
});
|
|||
|
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
|
|||
|
$this = $(this);
|
|||
|
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
|
|||
|
});
|
|||
|
$articleContent.on('click', '.anchor', function() {
|
|||
|
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
|
|||
|
});
|
|||
|
});
|
|||
|
});
|
|||
|
})();
|
|||
|
</script>
|
|||
|
|
|||
|
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
|
|||
|
<!-- end custom main bottom snippet -->
|
|||
|
</div>
|
|||
|
</div></div></div></div>
|
|||
|
</div><script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $body = $('body'), $window = $(window);
|
|||
|
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
|
|||
|
var activeCount = 0;
|
|||
|
function modal(options) {
|
|||
|
var $root = this, visible, onChange, hideWhenWindowScroll = false;
|
|||
|
var scrollTop;
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
visible = _options.initialVisible === undefined ? false : show;
|
|||
|
onChange = _options.onChange;
|
|||
|
hideWhenWindowScroll = _options.hideWhenWindowScroll;
|
|||
|
}
|
|||
|
function init() {
|
|||
|
setState(visible);
|
|||
|
}
|
|||
|
function setState(isShow) {
|
|||
|
if (isShow === visible) {
|
|||
|
return;
|
|||
|
}
|
|||
|
visible = isShow;
|
|||
|
if (visible) {
|
|||
|
activeCount++;
|
|||
|
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
|
|||
|
$root.addClass('modal--show');
|
|||
|
$pageMain.scrollTop(scrollTop);
|
|||
|
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
|
|||
|
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
|
|||
|
$window.on('keyup', handleKeyup);
|
|||
|
} else {
|
|||
|
activeCount > 0 && activeCount--;
|
|||
|
$root.removeClass('modal--show');
|
|||
|
$window.scrollTop(scrollTop);
|
|||
|
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
|
|||
|
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
|
|||
|
$window.off('keyup', handleKeyup);
|
|||
|
}
|
|||
|
onChange && onChange(visible);
|
|||
|
}
|
|||
|
function show() {
|
|||
|
setState(true);
|
|||
|
}
|
|||
|
function hide() {
|
|||
|
setState(false);
|
|||
|
}
|
|||
|
function handleKeyup(e) {
|
|||
|
// Char Code: 27 ESC
|
|||
|
if (e.which === 27) {
|
|||
|
hide();
|
|||
|
}
|
|||
|
}
|
|||
|
setOptions(options);
|
|||
|
init();
|
|||
|
return {
|
|||
|
show: show,
|
|||
|
hide: hide,
|
|||
|
$el: $root
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.modal = modal;
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
|
|||
|
(function () {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
// search panel
|
|||
|
var search = (window.search || (window.search = {}));
|
|||
|
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
|
|||
|
true : window.useDefaultSearchBox ;
|
|||
|
|
|||
|
var $searchModal = $('.js-page-search-modal');
|
|||
|
var $searchToggle = $('.js-search-toggle');
|
|||
|
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
|
|||
|
var modalVisible = false;
|
|||
|
search.searchModal = searchModal;
|
|||
|
|
|||
|
var $searchBox = null;
|
|||
|
var $searchInput = null;
|
|||
|
var $searchClear = null;
|
|||
|
|
|||
|
function getModalVisible() {
|
|||
|
return modalVisible;
|
|||
|
}
|
|||
|
search.getModalVisible = getModalVisible;
|
|||
|
|
|||
|
function handleModalChange(visible) {
|
|||
|
modalVisible = visible;
|
|||
|
if (visible) {
|
|||
|
search.onShow && search.onShow();
|
|||
|
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
|
|||
|
} else {
|
|||
|
search.onShow && search.onHide();
|
|||
|
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
|
|||
|
setTimeout(function() {
|
|||
|
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
|
|||
|
search.clear && search.clear();
|
|||
|
window.pageAsideAffix && window.pageAsideAffix.refresh();
|
|||
|
}, 400);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
$searchToggle.on('click', function() {
|
|||
|
modalVisible ? searchModal.hide() : searchModal.show();
|
|||
|
});
|
|||
|
// Char Code: 83 S, 191 /
|
|||
|
$(window).on('keyup', function(e) {
|
|||
|
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
|
|||
|
modalVisible || searchModal.show();
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
if (useDefaultSearchBox) {
|
|||
|
$searchBox = $('.js-search-box');
|
|||
|
$searchInput = $searchBox.children('input');
|
|||
|
$searchClear = $searchBox.children('.js-icon-clear');
|
|||
|
search.getSearchInput = function() {
|
|||
|
return $searchInput.get(0);
|
|||
|
};
|
|||
|
search.getVal = function() {
|
|||
|
return $searchInput.val();
|
|||
|
};
|
|||
|
search.setVal = function(val) {
|
|||
|
$searchInput.val(val);
|
|||
|
};
|
|||
|
|
|||
|
$searchInput.on('focus', function() {
|
|||
|
$(this).addClass('focus');
|
|||
|
});
|
|||
|
$searchInput.on('blur', function() {
|
|||
|
$(this).removeClass('focus');
|
|||
|
});
|
|||
|
$searchInput.on('input', window.throttle(function() {
|
|||
|
var val = $(this).val();
|
|||
|
if (val === '' || typeof val !== 'string') {
|
|||
|
search.clear && search.clear();
|
|||
|
} else {
|
|||
|
$searchBox.addClass('not-empty');
|
|||
|
search.onInputNotEmpty && search.onInputNotEmpty(val);
|
|||
|
}
|
|||
|
}, 400));
|
|||
|
$searchClear.on('click', function() {
|
|||
|
$searchInput.val(''); $searchBox.removeClass('not-empty');
|
|||
|
search.clear && search.clear();
|
|||
|
});
|
|||
|
}
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><div class="search search--dark">
|
|||
|
<div class="main">
|
|||
|
<div class="search__header">Recherche</div>
|
|||
|
<div class="search-bar">
|
|||
|
<div class="search-box js-search-box">
|
|||
|
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
|
|||
|
<input id="search-input" type="text" />
|
|||
|
<div class="search-box__icon-clear js-icon-clear">
|
|||
|
<a><i class="fas fa-times"></i></a>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
|
|||
|
Annuler</button>
|
|||
|
</div>
|
|||
|
<div id="results-container" class="search-result js-search-result"></div>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<!-- Script pointing to search-script.js -->
|
|||
|
<script>/*!
|
|||
|
* Simple-Jekyll-Search
|
|||
|
* Copyright 2015-2020, Christian Fei
|
|||
|
* Licensed under the MIT License.
|
|||
|
*/
|
|||
|
|
|||
|
(function(){
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Templater_7 = {
|
|||
|
compile: compile,
|
|||
|
setOptions: setOptions
|
|||
|
}
|
|||
|
|
|||
|
const options = {}
|
|||
|
options.pattern = /\{(.*?)\}/g
|
|||
|
options.template = ''
|
|||
|
options.middleware = function () {}
|
|||
|
|
|||
|
function setOptions (_options) {
|
|||
|
options.pattern = _options.pattern || options.pattern
|
|||
|
options.template = _options.template || options.template
|
|||
|
if (typeof _options.middleware === 'function') {
|
|||
|
options.middleware = _options.middleware
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function compile (data) {
|
|||
|
return options.template.replace(options.pattern, function (match, prop) {
|
|||
|
const value = options.middleware(prop, data[prop], options.template)
|
|||
|
if (typeof value !== 'undefined') {
|
|||
|
return value
|
|||
|
}
|
|||
|
return data[prop] || match
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
'use strict';
|
|||
|
|
|||
|
function fuzzysearch (needle, haystack) {
|
|||
|
var tlen = haystack.length;
|
|||
|
var qlen = needle.length;
|
|||
|
if (qlen > tlen) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
if (qlen === tlen) {
|
|||
|
return needle === haystack;
|
|||
|
}
|
|||
|
outer: for (var i = 0, j = 0; i < qlen; i++) {
|
|||
|
var nch = needle.charCodeAt(i);
|
|||
|
while (j < tlen) {
|
|||
|
if (haystack.charCodeAt(j++) === nch) {
|
|||
|
continue outer;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
var _$fuzzysearch_1 = fuzzysearch;
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
|
|||
|
|
|||
|
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
|
|||
|
|
|||
|
function FuzzySearchStrategy () {
|
|||
|
this.matches = function (string, crit) {
|
|||
|
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
|
|||
|
|
|||
|
function LiteralSearchStrategy () {
|
|||
|
this.matches = function (str, crit) {
|
|||
|
if (!str) return false
|
|||
|
|
|||
|
str = str.trim().toLowerCase()
|
|||
|
crit = crit.trim().toLowerCase()
|
|||
|
|
|||
|
return crit.split(' ').filter(function (word) {
|
|||
|
return str.indexOf(word) >= 0
|
|||
|
}).length === crit.split(' ').length
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$Repository_4 = {
|
|||
|
put: put,
|
|||
|
clear: clear,
|
|||
|
search: search,
|
|||
|
setOptions: __setOptions_4
|
|||
|
}
|
|||
|
|
|||
|
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
|
|||
|
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
|
|||
|
|
|||
|
function NoSort () {
|
|||
|
return 0
|
|||
|
}
|
|||
|
|
|||
|
const data = []
|
|||
|
let opt = {}
|
|||
|
|
|||
|
opt.fuzzy = false
|
|||
|
opt.limit = 10
|
|||
|
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = NoSort
|
|||
|
opt.exclude = []
|
|||
|
|
|||
|
function put (data) {
|
|||
|
if (isObject(data)) {
|
|||
|
return addObject(data)
|
|||
|
}
|
|||
|
if (isArray(data)) {
|
|||
|
return addArray(data)
|
|||
|
}
|
|||
|
return undefined
|
|||
|
}
|
|||
|
function clear () {
|
|||
|
data.length = 0
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function isObject (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
|
|||
|
}
|
|||
|
|
|||
|
function isArray (obj) {
|
|||
|
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
|
|||
|
}
|
|||
|
|
|||
|
function addObject (_data) {
|
|||
|
data.push(_data)
|
|||
|
return data
|
|||
|
}
|
|||
|
|
|||
|
function addArray (_data) {
|
|||
|
const added = []
|
|||
|
clear()
|
|||
|
for (let i = 0, len = _data.length; i < len; i++) {
|
|||
|
if (isObject(_data[i])) {
|
|||
|
added.push(addObject(_data[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
return added
|
|||
|
}
|
|||
|
|
|||
|
function search (crit) {
|
|||
|
if (!crit) {
|
|||
|
return []
|
|||
|
}
|
|||
|
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
|
|||
|
}
|
|||
|
|
|||
|
function __setOptions_4 (_opt) {
|
|||
|
opt = _opt || {}
|
|||
|
|
|||
|
opt.fuzzy = _opt.fuzzy || false
|
|||
|
opt.limit = _opt.limit || 10
|
|||
|
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
|
|||
|
opt.sort = _opt.sort || NoSort
|
|||
|
opt.exclude = _opt.exclude || []
|
|||
|
}
|
|||
|
|
|||
|
function findMatches (data, crit, strategy, opt) {
|
|||
|
const matches = []
|
|||
|
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
|
|||
|
const match = findMatchesInObject(data[i], crit, strategy, opt)
|
|||
|
if (match) {
|
|||
|
matches.push(match)
|
|||
|
}
|
|||
|
}
|
|||
|
return matches
|
|||
|
}
|
|||
|
|
|||
|
function findMatchesInObject (obj, crit, strategy, opt) {
|
|||
|
for (const key in obj) {
|
|||
|
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
|
|||
|
return obj
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isExcluded (term, excludedTerms) {
|
|||
|
for (let i = 0, len = excludedTerms.length; i < len; i++) {
|
|||
|
const excludedTerm = excludedTerms[i]
|
|||
|
if (new RegExp(excludedTerm).test(term)) {
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
/* globals ActiveXObject:false */
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$JSONLoader_2 = {
|
|||
|
load: load
|
|||
|
}
|
|||
|
|
|||
|
function load (location, callback) {
|
|||
|
const xhr = getXHR()
|
|||
|
xhr.open('GET', location, true)
|
|||
|
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
|
|||
|
xhr.send()
|
|||
|
}
|
|||
|
|
|||
|
function createStateChangeListener (xhr, callback) {
|
|||
|
return function () {
|
|||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|||
|
try {
|
|||
|
callback(null, JSON.parse(xhr.responseText))
|
|||
|
} catch (err) {
|
|||
|
callback(err, null)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getXHR () {
|
|||
|
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$OptionsValidator_3 = function OptionsValidator (params) {
|
|||
|
if (!validateParams(params)) {
|
|||
|
throw new Error('-- OptionsValidator: required options missing')
|
|||
|
}
|
|||
|
|
|||
|
if (!(this instanceof OptionsValidator)) {
|
|||
|
return new OptionsValidator(params)
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = params.required
|
|||
|
|
|||
|
this.getRequiredOptions = function () {
|
|||
|
return requiredOptions
|
|||
|
}
|
|||
|
|
|||
|
this.validate = function (parameters) {
|
|||
|
const errors = []
|
|||
|
requiredOptions.forEach(function (requiredOptionName) {
|
|||
|
if (typeof parameters[requiredOptionName] === 'undefined') {
|
|||
|
errors.push(requiredOptionName)
|
|||
|
}
|
|||
|
})
|
|||
|
return errors
|
|||
|
}
|
|||
|
|
|||
|
function validateParams (params) {
|
|||
|
if (!params) {
|
|||
|
return false
|
|||
|
}
|
|||
|
return typeof params.required !== 'undefined' && params.required instanceof Array
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
'use strict'
|
|||
|
|
|||
|
var _$utils_9 = {
|
|||
|
merge: merge,
|
|||
|
isJSON: isJSON
|
|||
|
}
|
|||
|
|
|||
|
function merge (defaultParams, mergeParams) {
|
|||
|
const mergedOptions = {}
|
|||
|
for (const option in defaultParams) {
|
|||
|
mergedOptions[option] = defaultParams[option]
|
|||
|
if (typeof mergeParams[option] !== 'undefined') {
|
|||
|
mergedOptions[option] = mergeParams[option]
|
|||
|
}
|
|||
|
}
|
|||
|
return mergedOptions
|
|||
|
}
|
|||
|
|
|||
|
function isJSON (json) {
|
|||
|
try {
|
|||
|
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
|
|||
|
return true
|
|||
|
}
|
|||
|
return false
|
|||
|
} catch (err) {
|
|||
|
return false
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var _$src_8 = {};
|
|||
|
(function (window) {
|
|||
|
'use strict'
|
|||
|
|
|||
|
let options = {
|
|||
|
searchInput: null,
|
|||
|
resultsContainer: null,
|
|||
|
json: [],
|
|||
|
success: Function.prototype,
|
|||
|
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
|
|||
|
templateMiddleware: Function.prototype,
|
|||
|
sortMiddleware: function () {
|
|||
|
return 0
|
|||
|
},
|
|||
|
noResultsText: 'No results found',
|
|||
|
limit: 10,
|
|||
|
fuzzy: false,
|
|||
|
debounceTime: null,
|
|||
|
exclude: []
|
|||
|
}
|
|||
|
|
|||
|
let debounceTimerHandle
|
|||
|
const debounce = function (func, delayMillis) {
|
|||
|
if (delayMillis) {
|
|||
|
clearTimeout(debounceTimerHandle)
|
|||
|
debounceTimerHandle = setTimeout(func, delayMillis)
|
|||
|
} else {
|
|||
|
func.call()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
|
|||
|
|
|||
|
/* removed: const _$Templater_7 = require('./Templater') */;
|
|||
|
/* removed: const _$Repository_4 = require('./Repository') */;
|
|||
|
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
|
|||
|
const optionsValidator = _$OptionsValidator_3({
|
|||
|
required: requiredOptions
|
|||
|
})
|
|||
|
/* removed: const _$utils_9 = require('./utils') */;
|
|||
|
|
|||
|
window.SimpleJekyllSearch = function (_options) {
|
|||
|
const errors = optionsValidator.validate(_options)
|
|||
|
if (errors.length > 0) {
|
|||
|
throwError('You must specify the following required options: ' + requiredOptions)
|
|||
|
}
|
|||
|
|
|||
|
options = _$utils_9.merge(options, _options)
|
|||
|
|
|||
|
_$Templater_7.setOptions({
|
|||
|
template: options.searchResultTemplate,
|
|||
|
middleware: options.templateMiddleware
|
|||
|
})
|
|||
|
|
|||
|
_$Repository_4.setOptions({
|
|||
|
fuzzy: options.fuzzy,
|
|||
|
limit: options.limit,
|
|||
|
sort: options.sortMiddleware,
|
|||
|
exclude: options.exclude
|
|||
|
})
|
|||
|
|
|||
|
if (_$utils_9.isJSON(options.json)) {
|
|||
|
initWithJSON(options.json)
|
|||
|
} else {
|
|||
|
initWithURL(options.json)
|
|||
|
}
|
|||
|
|
|||
|
const rv = {
|
|||
|
search: search
|
|||
|
}
|
|||
|
|
|||
|
typeof options.success === 'function' && options.success.call(rv)
|
|||
|
return rv
|
|||
|
}
|
|||
|
|
|||
|
function initWithJSON (json) {
|
|||
|
_$Repository_4.put(json)
|
|||
|
registerInput()
|
|||
|
}
|
|||
|
|
|||
|
function initWithURL (url) {
|
|||
|
_$JSONLoader_2.load(url, function (err, json) {
|
|||
|
if (err) {
|
|||
|
throwError('failed to get JSON (' + url + ')')
|
|||
|
}
|
|||
|
initWithJSON(json)
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function emptyResultsContainer () {
|
|||
|
options.resultsContainer.innerHTML = ''
|
|||
|
}
|
|||
|
|
|||
|
function appendToResultsContainer (text) {
|
|||
|
options.resultsContainer.innerHTML += text
|
|||
|
}
|
|||
|
|
|||
|
function registerInput () {
|
|||
|
options.searchInput.addEventListener('input', function (e) {
|
|||
|
if (isWhitelistedKey(e.which)) {
|
|||
|
emptyResultsContainer()
|
|||
|
debounce(function () { search(e.target.value) }, options.debounceTime)
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
function search (query) {
|
|||
|
if (isValidQuery(query)) {
|
|||
|
emptyResultsContainer()
|
|||
|
render(_$Repository_4.search(query), query)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function render (results, query) {
|
|||
|
const len = results.length
|
|||
|
if (len === 0) {
|
|||
|
return appendToResultsContainer(options.noResultsText)
|
|||
|
}
|
|||
|
for (let i = 0; i < len; i++) {
|
|||
|
results[i].query = query
|
|||
|
appendToResultsContainer(_$Templater_7.compile(results[i]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isValidQuery (query) {
|
|||
|
return query && query.length > 0
|
|||
|
}
|
|||
|
|
|||
|
function isWhitelistedKey (key) {
|
|||
|
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
|
|||
|
}
|
|||
|
|
|||
|
function throwError (message) {
|
|||
|
throw new Error('SimpleJekyllSearch --- ' + message)
|
|||
|
}
|
|||
|
})(window)
|
|||
|
|
|||
|
}());
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- Configuration -->
|
|||
|
<script>
|
|||
|
SimpleJekyllSearch({
|
|||
|
searchInput: document.getElementById('search-input'),
|
|||
|
resultsContainer: document.getElementById('results-container'),
|
|||
|
noResultsText: '<p>Aucun résultat!</p>',
|
|||
|
json: '/search.json',
|
|||
|
searchResultTemplate: '<li><a href="{url}">{date} {title}</a> (Création {create})</li>'
|
|||
|
})
|
|||
|
</script>
|
|||
|
|
|||
|
</div></div>
|
|||
|
|
|||
|
|
|||
|
<script>(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function scrollToAnchor(anchor, duration, callback) {
|
|||
|
var $root = this;
|
|||
|
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
|
|||
|
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
|
|||
|
callback && callback();
|
|||
|
});
|
|||
|
}
|
|||
|
$.fn.scrollToAnchor = scrollToAnchor;
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function affix(options) {
|
|||
|
var $root = this, $window = $(window), $scrollTarget, $scroll,
|
|||
|
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
|
|||
|
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
|
|||
|
hasInit = false, curState;
|
|||
|
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
|
|||
|
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
|||
|
_options.scroll && (scroll = _options.scroll);
|
|||
|
_options.disabled !== undefined && (disabled = _options.disabled);
|
|||
|
$scrollTarget = $(scrollTarget);
|
|||
|
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
|
|||
|
$scroll = $(scroll);
|
|||
|
}
|
|||
|
function preCalc() {
|
|||
|
top();
|
|||
|
rootHeight = $root.outerHeight();
|
|||
|
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
|
|||
|
rootLeft = $root.offset().left;
|
|||
|
}
|
|||
|
function calc(needPreCalc) {
|
|||
|
needPreCalc && preCalc();
|
|||
|
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
|
|||
|
rootBottomTop = scrollBottom - rootTop;
|
|||
|
}
|
|||
|
function top() {
|
|||
|
if (curState !== 'top') {
|
|||
|
$root.removeClass('fixed').css({
|
|||
|
left: 0,
|
|||
|
top: 0
|
|||
|
});
|
|||
|
curState = 'top';
|
|||
|
}
|
|||
|
}
|
|||
|
function fixed() {
|
|||
|
if (curState !== 'fixed') {
|
|||
|
$root.addClass('fixed').css({
|
|||
|
left: rootLeft + 'px',
|
|||
|
top: 0
|
|||
|
});
|
|||
|
curState = 'fixed';
|
|||
|
}
|
|||
|
}
|
|||
|
function bottom() {
|
|||
|
if (curState !== 'bottom') {
|
|||
|
$root.removeClass('fixed').css({
|
|||
|
left: 0,
|
|||
|
top: rootBottomTop + 'px'
|
|||
|
});
|
|||
|
curState = 'bottom';
|
|||
|
}
|
|||
|
}
|
|||
|
function setState() {
|
|||
|
var scrollTop = $scrollTarget.scrollTop();
|
|||
|
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
|
|||
|
fixed();
|
|||
|
} else if (scrollTop < rootTop) {
|
|||
|
top();
|
|||
|
} else {
|
|||
|
bottom();
|
|||
|
}
|
|||
|
}
|
|||
|
function init() {
|
|||
|
if(!hasInit) {
|
|||
|
var interval, timeout;
|
|||
|
calc(true); setState();
|
|||
|
// run calc every 100 millisecond
|
|||
|
interval = setInterval(function() {
|
|||
|
calc();
|
|||
|
}, 100);
|
|||
|
timeout = setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
}, 45000);
|
|||
|
window.pageLoad.then(function() {
|
|||
|
setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
clearTimeout(timeout);
|
|||
|
}, 3000);
|
|||
|
});
|
|||
|
$scrollTarget.on('scroll', function() {
|
|||
|
disabled || setState();
|
|||
|
});
|
|||
|
$window.on('resize', function() {
|
|||
|
disabled || (calc(true), setState());
|
|||
|
});
|
|||
|
hasInit = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
setOptions(options);
|
|||
|
if (!disabled) {
|
|||
|
init();
|
|||
|
}
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
init();
|
|||
|
}, 200));
|
|||
|
return {
|
|||
|
setOptions: setOptions,
|
|||
|
refresh: function() {
|
|||
|
calc(true, { animation: false }); setState();
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.affix = affix;
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
function toc(options) {
|
|||
|
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
|||
|
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
|||
|
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
|||
|
|
|||
|
function setOptions(options) {
|
|||
|
var _options = options || {};
|
|||
|
_options.selectors && (selectors = _options.selectors);
|
|||
|
_options.container && (container = _options.container);
|
|||
|
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
|||
|
_options.scroller && (scroller = _options.scroller);
|
|||
|
_options.disabled !== undefined && (disabled = _options.disabled);
|
|||
|
$headings = $(container).find(selectors).filter('[id]');
|
|||
|
$scrollTarget = $(scrollTarget);
|
|||
|
$scroller = $(scroller);
|
|||
|
}
|
|||
|
function calc() {
|
|||
|
headingsPos = [];
|
|||
|
$headings.each(function() {
|
|||
|
headingsPos.push(Math.floor($(this).position().top));
|
|||
|
});
|
|||
|
}
|
|||
|
function setState(element, disabled) {
|
|||
|
var scrollTop = $scrollTarget.scrollTop(), i;
|
|||
|
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
|||
|
if (element) {
|
|||
|
$activeCur = element;
|
|||
|
} else {
|
|||
|
for (i = 0; i < headingsPos.length; i++) {
|
|||
|
if (scrollTop >= headingsPos[i]) {
|
|||
|
$activeCur = $tocLi.eq(i);
|
|||
|
} else {
|
|||
|
$activeCur || ($activeCur = $tocLi.eq(i));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
$activeLast && $activeLast.removeClass('active');
|
|||
|
($activeLast = $activeCur).addClass('active');
|
|||
|
}
|
|||
|
function render() {
|
|||
|
if(!hasRendered) {
|
|||
|
$root.append($tocUl);
|
|||
|
$headings.each(function() {
|
|||
|
var $this = $(this);
|
|||
|
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
|||
|
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
|||
|
});
|
|||
|
$tocLi = $tocUl.children('li');
|
|||
|
$tocUl.on('click', 'a', function(e) {
|
|||
|
e.preventDefault();
|
|||
|
var $this = $(this);
|
|||
|
scrolling = true;
|
|||
|
setState($this.parent());
|
|||
|
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
|||
|
scrolling = false;
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
hasRendered = true;
|
|||
|
}
|
|||
|
function init() {
|
|||
|
var interval, timeout;
|
|||
|
if(!hasInit) {
|
|||
|
render(); calc(); setState(null, scrolling);
|
|||
|
// run calc every 100 millisecond
|
|||
|
interval = setInterval(function() {
|
|||
|
calc();
|
|||
|
}, 100);
|
|||
|
timeout = setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
}, 45000);
|
|||
|
window.pageLoad.then(function() {
|
|||
|
setTimeout(function() {
|
|||
|
clearInterval(interval);
|
|||
|
clearTimeout(timeout);
|
|||
|
}, 3000);
|
|||
|
});
|
|||
|
$scrollTarget.on('scroll', function() {
|
|||
|
disabled || setState(null, scrolling);
|
|||
|
});
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
if (!disabled) {
|
|||
|
render(); calc(); setState(null, scrolling);
|
|||
|
}
|
|||
|
}, 100));
|
|||
|
}
|
|||
|
hasInit = true;
|
|||
|
}
|
|||
|
|
|||
|
setOptions(options);
|
|||
|
if (!disabled) {
|
|||
|
init();
|
|||
|
}
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
init();
|
|||
|
}, 200));
|
|||
|
return {
|
|||
|
setOptions: setOptions
|
|||
|
};
|
|||
|
}
|
|||
|
$.fn.toc = toc;
|
|||
|
});
|
|||
|
})();
|
|||
|
/*(function () {
|
|||
|
|
|||
|
})();*/
|
|||
|
</script><script>
|
|||
|
/* toc must before affix, since affix need to konw toc' height. */(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $window = $(window);
|
|||
|
var $articleContent = $('.js-article-content');
|
|||
|
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
|
|||
|
var toc;
|
|||
|
var tocDisabled = false;
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
|
|||
|
|
|||
|
function disabled() {
|
|||
|
return $col2.css('display') === 'none' || !hasToc;
|
|||
|
}
|
|||
|
|
|||
|
tocDisabled = disabled();
|
|||
|
|
|||
|
toc = $tocRoot.toc({
|
|||
|
selectors: TOC_SELECTOR,
|
|||
|
container: $articleContent,
|
|||
|
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroller: hasSidebar ? '.js-page-main' : null,
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
tocDisabled = disabled();
|
|||
|
toc && toc.setOptions({
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
}, 100));
|
|||
|
|
|||
|
});
|
|||
|
})();
|
|||
|
(function() {
|
|||
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|||
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|||
|
var $window = $(window), $pageFooter = $('.js-page-footer');
|
|||
|
var $pageAside = $('.js-page-aside');
|
|||
|
var affix;
|
|||
|
var tocDisabled = false;
|
|||
|
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
|
|||
|
|
|||
|
affix = $pageAside.affix({
|
|||
|
offsetBottom: $pageFooter.outerHeight(),
|
|||
|
scrollTarget: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroller: hasSidebar ? '.js-page-main' : null,
|
|||
|
scroll: hasSidebar ? $('.js-page-main').children() : null,
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
|
|||
|
$window.on('resize', window.throttle(function() {
|
|||
|
affix && affix.setOptions({
|
|||
|
disabled: tocDisabled
|
|||
|
});
|
|||
|
}, 100));
|
|||
|
|
|||
|
window.pageAsideAffix = affix;
|
|||
|
});
|
|||
|
})();
|
|||
|
</script><!---->
|
|||
|
|
|||
|
</div>
|
|||
|
<script>(function () {
|
|||
|
var $root = document.getElementsByClassName('root')[0];
|
|||
|
if (window.hasEvent('touchstart')) {
|
|||
|
$root.dataset.isTouch = true;
|
|||
|
document.addEventListener('touchstart', function(){}, false);
|
|||
|
}
|
|||
|
})();
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|
|||
|
|