3345 lines
271 KiB
HTML
3345 lines
271 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>Contabo Debian 11 (Bullseye) xoyize.xyz - YannStatic</title>
|
|||
|
|
|||
|
<meta name="description" content="https://contabo.com/en/">
|
|||
|
<link rel="canonical" href="https://static.rnmkcy.eu/2022/11/15/VPS-Contabo-Debian-11.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;">Contabo Debian 11 (Bullseye) xoyize.xyz</h1></header></div><meta itemprop="headline" content="Contabo Debian 11 (Bullseye) xoyize.xyz"><div class="article__info clearfix"><ul class="left-col menu"><li>
|
|||
|
<a class="button button--secondary button--pill button--sm"
|
|||
|
href="/archive.html?tag=vps">vps</a>
|
|||
|
</li></ul><ul class="right-col menu"><li>
|
|||
|
<i class="far fa-calendar-alt"></i> <span title="Création" style="color:#FF00FF">15 nov. 2022</span>
|
|||
|
|
|||
|
<span title="Modification" style="color:#00FF7F">16 nov. 2022</span></li></ul></div><meta itemprop="datePublished" content="2022-11-16T00:00:00+01:00">
|
|||
|
<meta itemprop="keywords" content="vps"><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/contabo-logo-a.png" alt="Contabo" /><br />
|
|||
|
<a href="https://contabo.com/en/">https://contabo.com/en/</a></p>
|
|||
|
|
|||
|
<p>Fournisseur : <strong>Contabo</strong><br />
|
|||
|
Accès client : <a href="https://my.contabo.com/">https://my.contabo.com/</a><br />
|
|||
|
Nom du plan : <strong>VPS S SSD</strong><br />
|
|||
|
Location Nuremberg (EU)<br />
|
|||
|
RAM garantie : <strong>8192 Mb</strong><br />
|
|||
|
Bande passante mensuelle illimitée<br />
|
|||
|
<strong>Espace disque SSD 200 Go</strong><br />
|
|||
|
Système d’exploitation : <strong>Debian 11</strong><br />
|
|||
|
Technologie de virtualisation <strong>KVM</strong><br />
|
|||
|
Emplacement du serveur Allemagne <img src="/images/de.png" alt="" /><br />
|
|||
|
Frais d’installation 0.00 EUR<br />
|
|||
|
Coût annuel 86.28€/An TTC<br />
|
|||
|
Méthodes de paiement PayPal</p>
|
|||
|
|
|||
|
<p>IP address <strong>109.123.254.249</strong><br />
|
|||
|
Accès client : <a href="https://my.contabo.com/">https://my.contabo.com/</a></p>
|
|||
|
|
|||
|
<p>Autorisation à deux facteurs : <a href="https://my.contabo.com/">https://my.contabo.com/</a> → Customer details et <strong>Activate 2-factor authentication</strong><br />
|
|||
|
Activer le reverse DNS IPV4 et IPV6 pour le domaine xoyize.xyz : Control panel → Reverse DNS management<br />
|
|||
|
Désactiver VNC: Your services → Manage → VPS Control → Manage → Disable VNC et valider par un clic sur Disable</p>
|
|||
|
|
|||
|
<p>Sous-réseau IPv6 <br />
|
|||
|
<em>Chaque serveur dédié et chaque VPS est livré avec un sous-réseau IPv6 /64 en plus de son adresse IPv4. Vous pouvez utiliser les adresses de ce sous-réseau librement sur le serveur/VPS associé. IPv6 est déjà préconfiguré sur nos serveurs mais doit être activé explicitement dans certains cas. Vous trouverez comment activer IPv6 et d’autres informations sur le sujet dans notre tutoriel.</em></p>
|
|||
|
|
|||
|
<table>
|
|||
|
<thead>
|
|||
|
<tr>
|
|||
|
<th style="text-align: left">type d’abonnement</th>
|
|||
|
<th style="text-align: left">adresse IPv4</th>
|
|||
|
<th style="text-align: left">sous-réseau IPv6</th>
|
|||
|
</tr>
|
|||
|
</thead>
|
|||
|
<tbody>
|
|||
|
<tr>
|
|||
|
<td style="text-align: left">VPS S SSD (no setup)</td>
|
|||
|
<td style="text-align: left">109.123.254.249</td>
|
|||
|
<td style="text-align: left">2a02:c206:2108:3749::1 / 64</td>
|
|||
|
</tr>
|
|||
|
</tbody>
|
|||
|
</table>
|
|||
|
|
|||
|
<h2 id="debian-bullseye">Debian bullseye</h2>
|
|||
|
|
|||
|
<p><img src="/images/debian11-logo-a.png" alt="" height="60" /></p>
|
|||
|
|
|||
|
<p>PARAMETRES D’ACCES:<br />
|
|||
|
L’adresse IPv4 du VPS est : 109.123.254.249<br />
|
|||
|
L’adresse IPv6 du VPS est : 2a02:c206:2108:3749::1</p>
|
|||
|
|
|||
|
<p>On se connecte en root sur le VPS</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh root@109.123.254.249
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Linux vmi1083749.contaboserver.net 5.10.0-12-amd64 #1 SMP Debian 5.10.103-1 (2022-03-07) x86_64
|
|||
|
_____
|
|||
|
/ ___/___ _ _ _____ _ ___ ___
|
|||
|
| | / _ \| \| |_ _/ \ | _ )/ _ \
|
|||
|
| |__| (_) | .` | | |/ _ \| _ \ (_) |
|
|||
|
\____\___/|_|\_| |_/_/ \_|___/\___/
|
|||
|
|
|||
|
Welcome!
|
|||
|
|
|||
|
This server is hosted by Contabo. If you have any questions or need help,
|
|||
|
please don't hesitate to contact us at support@contabo.com.
|
|||
|
|
|||
|
root@vmi1083749:~#
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="mise-à-jour--réseau-ipv6">Mise à jour + Réseau IPV6</h3>
|
|||
|
|
|||
|
<p><strong>Mise à jour</strong>, exécuter <code class="language-plaintext highlighter-rouge">apt update && apt upgrade</code><br />
|
|||
|
<strong>Quelques outils</strong>, exécuter <code class="language-plaintext highlighter-rouge">apt install tree tmux</code><br />
|
|||
|
<strong>Activation ipv6</strong>, exécuter <code class="language-plaintext highlighter-rouge">enable_ipv6</code> puis redémarrer <code class="language-plaintext highlighter-rouge">reboot</code> et se reconnecter ssh</p>
|
|||
|
|
|||
|
<p>Vérifier l’adressage : <code class="language-plaintext highlighter-rouge">ip a</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext 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
|
|||
|
link/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
|
|||
|
link/ether 00:50:56:48:b5:5b brd ff:ff:ff:ff:ff:ff
|
|||
|
altname enp0s18
|
|||
|
altname ens18
|
|||
|
inet 109.123.254.249/20 brd 109.123.255.255 scope global eth0
|
|||
|
valid_lft forever preferred_lft forever
|
|||
|
inet6 2a02:c206:2108:3749::1/64 scope global
|
|||
|
valid_lft forever preferred_lft forever
|
|||
|
inet6 fe80::250:56ff:fe48:b55b/64 scope link
|
|||
|
valid_lft forever preferred_lft forever
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="date-et-heure--synchro">Date et heure + Synchro</h3>
|
|||
|
|
|||
|
<p><img src="/images/timezone-france.png" alt="" height="40" /><br />
|
|||
|
Activer le fuseau Europe/Paris</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>timedatectl set-timezone Europe/Paris
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Horloge système synchronisée</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>timedatectl
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Local time: Mon 2022-11-14 17:15:19 CET
|
|||
|
Universal time: Mon 2022-11-14 16:15:19 UTC
|
|||
|
RTC time: Mon 2022-11-14 16:15:20
|
|||
|
Time zone: Europe/Paris (CET, +0100)
|
|||
|
System clock synchronized: yes
|
|||
|
NTP service: active
|
|||
|
RTC in local TZ: no
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="reconfigurer-locales">Reconfigurer locales</h3>
|
|||
|
|
|||
|
<p>Activer uniquement <strong>en_US.UTF-8</strong> et <strong>fr_FR.UTF-8</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>dpkg-reconfigure locales
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Generating locales (this might take a while)...
|
|||
|
en_US.UTF-8... done
|
|||
|
fr_FR.UTF-8... done
|
|||
|
Generation complete.
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="dnsmasq">dnsmasq</h3>
|
|||
|
|
|||
|
<p><img src="/images/Dnsmasq_logo.png" alt="" /><br />
|
|||
|
<a href="/2019/12/25/DNSmasq.html">DNSmasq (installation et configuration)</a></p>
|
|||
|
|
|||
|
<p>Installer dnsmasq</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install dnsmasq
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le paramétrage réseau par défaut <code class="language-plaintext highlighter-rouge">/etc/network/interfaces</code><br />
|
|||
|
Il faut commenter les lignes <code class="language-plaintext highlighter-rouge">dns-</code> pour utiliser dnsmasq</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># The loopback network interface
|
|||
|
auto lo
|
|||
|
iface lo inet loopback
|
|||
|
|
|||
|
# The primary network interface
|
|||
|
auto eth0
|
|||
|
iface eth0 inet static
|
|||
|
address 109.123.254.249
|
|||
|
netmask 255.255.240.0
|
|||
|
gateway 109.123.240.1
|
|||
|
#dns-search invalid
|
|||
|
#dns-nameservers 161.97.189.52 161.97.189.51
|
|||
|
up ip route replace 109.123.240.0/20 via 109.123.240.1 dev eth0
|
|||
|
|
|||
|
|
|||
|
iface eth0 inet6 static
|
|||
|
address 2a02:c206:2108:3749:0000:0000:0000:0001
|
|||
|
netmask 64
|
|||
|
gateway fe80::1
|
|||
|
accept_ra 0
|
|||
|
autoconf 0
|
|||
|
privext 0
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Configuration de dnsmasq en éditant le fichier <code class="language-plaintext highlighter-rouge">/etc/resolv.conf</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>search contaboserver.net
|
|||
|
nameserver 161.97.189.51
|
|||
|
nameserver 161.97.189.52
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vous devez faire en sorte que toutes les requêtes soient envoyées à dnsmasq en ajoutant les adresses localhost comme seuls serveurs de noms dans le fichier <code class="language-plaintext highlighter-rouge">/etc/resolv.conf</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nameserver 127.0.0.1
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Faire une sauvegarde du fichier <code class="language-plaintext highlighter-rouge">mv /etc/dnsmasq.conf /etc/dnsmasq.conf.default</code><br />
|
|||
|
Créer le fichier <code class="language-plaintext highlighter-rouge">/etc/dnsmasq.conf</code> et effectuer les réglages de configuration</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>domain-needed
|
|||
|
expand-hosts
|
|||
|
localise-queries
|
|||
|
|
|||
|
<span class="nv">interface</span><span class="o">=</span>lo
|
|||
|
|
|||
|
resolv-file<span class="o">=</span>/etc/resolv.dnsmasq.conf
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Explications</p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><strong>domain-needed</strong> : Ne transmet pas les requêtes ne contenant pas un nom de domaine complet. Par exemple,une requête pour machine ne sera pas transmise aux serveurs DNS de votre FAI, alors qu’une requête pour machine.domain.com le sera.</li>
|
|||
|
<li>Si vous souhaitez qu’un domaine soit automatiquement ajouté aux noms simples dans un fichier hosts, décommentez l’option <strong>expand-hosts</strong></li>
|
|||
|
<li><strong>localise-queries</strong> : Retourne des réponses aux requêtes DNS dépendantes de l’interface sur laquelle la requête a été reçue, à partir du fichier /etc/hosts. Si un nom dans /etc/hosts a plus d’une adresse associée avec lui, et qu’une des adresses au moins est dans le même sous-réseau que l’interface sur laquelle la requête a été reçue, alors ne retourne que la(les) adresse(s) du sous-réseau considéré. Cela permet d’avoir dans /etc/hosts un serveur avec de multiples adresses, une pour chacune de ses interfaces, et de fournir aux hôtes l’adresse correcte (basée sur le réseau auquel ils sont attachés). Cette possibilité est actuellement limitée à IPv4.</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<p>Pour lutter contre la censure sur Internet, <a href="https://www.fdn.fr/actions/dns/">FDN</a> fait le choix de mettre à disposition de toutes et tous des résolveurs DNS récursifs ouverts.<br />
|
|||
|
Le fichier des dns <code class="language-plaintext highlighter-rouge">/etc/resolv.dnsmasq.conf</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nameserver 80.67.169.12
|
|||
|
nameserver 2001:910:800::12
|
|||
|
nameserver 80.67.169.40
|
|||
|
nameserver 2001:910:800::40
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Redémarrer dnsmasq</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart dnsmasq
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérifications, installer dnsutils au préalable (<code class="language-plaintext highlighter-rouge">apt install dnsutils</code>)</p>
|
|||
|
|
|||
|
<p><img src="/images/contabo001.png" alt="" /></p>
|
|||
|
|
|||
|
<h3 id="création-utilisateur">Création utilisateur</h3>
|
|||
|
|
|||
|
<p><img src="/images/user-logo.png" alt="" height="50" /><br />
|
|||
|
Utilisateur <strong>ctbouser</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>useradd -m -d /home/ctbouser/ -s /bin/bash ctbouser
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Mot de passe <strong>ctbouser</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>passwd ctbouser
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Visudo pour les accès root via utilisateur <strong>ctbouser</strong>, installer sudo : <code class="language-plaintext highlighter-rouge">apt install sudo</code></p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"ctbouser ALL=(ALL) NOPASSWD: ALL"</span> <span class="o">>></span> /etc/sudoers
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Déconnexion puis connexion ssh en mode utilisateur</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh ctbouser@109.123.254.249
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="openssh-clé-et-script">OpenSSH, clé et script</h3>
|
|||
|
|
|||
|
<p><img src="/images/ssh_logo1.png" alt="OpenSSH" height="50" /><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) pour une liaison SSH avec le serveur.</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/contabovps
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Envoyer les clés publiques sur le serveur KVM</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-copy-id -i ~/.ssh/contabovps.pub ctbouser@109.123.254.249
|
|||
|
</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 ctbouser@109.123.254.249
|
|||
|
</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
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier</p>
|
|||
|
|
|||
|
<div class="language-conf highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Port</span> = <span class="m">55249</span>
|
|||
|
<span class="n">PermitRootLogin</span> <span class="n">no</span> <span class="c"># en fin de fichier
|
|||
|
</span><span class="n">PasswordAuthentication</span> <span class="n">no</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<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>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 ctbouser@109.123.254.249 -p 55249 -i ~/.ssh/contabovps
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="outils-scripts-motd-et-ssh_rc_bash">Outils, scripts motd et ssh_rc_bash</h3>
|
|||
|
|
|||
|
<p><img src="/images/bash-shell-logo.png" alt="" height="50" /><br />
|
|||
|
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 tree
|
|||
|
</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-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ___ _ _
|
|||
|
/ __| ___ _ _ | |_ __ _ | |__ ___
|
|||
|
| (__ / _ \| ' \| _|/ _` || '_ \/ _ \
|
|||
|
\___|\___/|_||_|\__|\__,_||_.__/\___/
|
|||
|
_ __ ___ _ ___ ____ ___ ___ _ _ ___ _ _ ___
|
|||
|
/ | / \ / _ \ / ||_ )|__ / |_ )| __|| | | |_ )| | | / _ \
|
|||
|
| || () |\_, /_ | | / / |_ \ _ / / |__ \|_ _|_ / / |_ _|\_, /
|
|||
|
|_| \__/ /_/(_)|_|/___||___/(_)/___||___/ |_|(_)/___| |_| /_/
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Script <strong>ssh_rc_bash</strong></p>
|
|||
|
<blockquote>
|
|||
|
<p><strong>ATTENTION!!! Les scripts sur connexion peuvent poser des problèmes pour des appels externes autres que ssh</strong></p>
|
|||
|
</blockquote>
|
|||
|
|
|||
|
<div class="language-shell 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/contabo002.png" alt="Texte alternatif" /></p>
|
|||
|
|
|||
|
<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<br />
|
|||
|
Se connecter en utilisateur debian<br />
|
|||
|
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
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="parefeu-ufw">Parefeu UFW</h3>
|
|||
|
|
|||
|
<p><img src="/images/ufw-logo-a.png" alt="ufw" width="50" /></p>
|
|||
|
|
|||
|
<p><em>UFW, ou pare - feu simple , est une interface pour gérer les règles de pare-feu dans Arch Linux, Debian ou Ubuntu. UFW est utilisé via la ligne de commande (bien qu’il dispose d’interfaces graphiques disponibles), et vise à rendre la configuration du pare-feu facile.</em></p>
|
|||
|
|
|||
|
<p>Installation <strong>Debian / Ubuntu</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install ufw
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><em>Par défaut, les jeux de règles d’UFW sont vides, de sorte qu’il n’applique aucune règle de pare-feu, même lorsque le démon est en cours d’exécution.</em></p>
|
|||
|
|
|||
|
<p>Les règles</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>ufw allow 55249/tcp <span class="c"># port SSH</span>
|
|||
|
<span class="nb">sudo </span>ufw allow http <span class="c"># port 80</span>
|
|||
|
<span class="nb">sudo </span>ufw allow https <span class="c"># port 443</span>
|
|||
|
<span class="nb">sudo </span>ufw allow DNS <span class="c"># port 53</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Activer le parefeu</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo ufw enable
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
|
|||
|
Firewall is active and enabled on system startup
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Status</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> sudo ufw status verbose
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Status: active
|
|||
|
Logging: on (low)
|
|||
|
Default: deny (incoming), allow (outgoing), disabled (routed)
|
|||
|
New profiles: skip
|
|||
|
|
|||
|
To Action From
|
|||
|
-- ------ ----
|
|||
|
55249/tcp ALLOW IN Anywhere
|
|||
|
80/tcp ALLOW IN Anywhere
|
|||
|
443 ALLOW IN Anywhere
|
|||
|
53 (DNS) ALLOW IN Anywhere
|
|||
|
55249/tcp (v6) ALLOW IN Anywhere (v6)
|
|||
|
80/tcp (v6) ALLOW IN Anywhere (v6)
|
|||
|
443 (v6) ALLOW IN Anywhere (v6)
|
|||
|
53 (DNS (v6)) ALLOW IN Anywhere (v6)
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="nginx-compilé">Nginx compilé</h3>
|
|||
|
|
|||
|
<p><img src="/images/Nginx-logo-large.png" alt="" height="50" /></p>
|
|||
|
|
|||
|
<p>Utilisateur avec droits sudo</p>
|
|||
|
|
|||
|
<p>Télécharger le bash</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget https://static.xoyaz.xyz/files/compilation-nginx-tls1.3.sh
|
|||
|
<span class="nb">chmod</span> +x compilation-nginx-tls1.3.sh <span class="c"># rendre le bash exécutable</span>
|
|||
|
./compilation-nginx-tls1.3.sh <span class="c"># exécution</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>A la fin de la compilation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Versions Nginx OpenSSL
|
|||
|
nginx version: nginx/1.22.1
|
|||
|
OpenSSL 1.1.1n 15 Mar 2022
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="domaine-et-certificats">Domaine et certificats</h3>
|
|||
|
|
|||
|
<p>Se connecter sur HMS pour configurer le reverse dns <br />
|
|||
|
109.123.254.249 –> xoyize.xyz<br />
|
|||
|
Demander par ticket la modification du reverse dns ipv6<br />
|
|||
|
2a04:ecc0:8:a8:4567:4989:0:1 –> xoyize.xyz</p>
|
|||
|
|
|||
|
<p>Changer le hostname</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo hostnamectl set-hostname xoyize.xyz
|
|||
|
hostnamectl
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Static hostname: xoyize.xyz
|
|||
|
Icon name: computer-vm
|
|||
|
Chassis: vm
|
|||
|
Machine ID: 9e9b14b1d9ae21acbd3793ac63720d60
|
|||
|
Boot ID: 75f900123d6b48bab465343fddbf3999
|
|||
|
Virtualization: kvm
|
|||
|
Operating System: Debian GNU/Linux 11 (bullseye)
|
|||
|
Kernel: Linux 5.10.0-19-amd64
|
|||
|
Architecture: x86-64
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="ovh-domaine-xoyizexyz">OVH domaine xoyize.xyz</h4>
|
|||
|
|
|||
|
<p><img src="/images/dns-logo.png" alt="dns" width="50" /><br />
|
|||
|
<img src="/images/ovh-logo-a.png" alt="dns" width="50" /> configuration domaine <strong>xoyize.xyz</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$TTL 3600
|
|||
|
@ IN SOA dns106.ovh.net. tech.ovh.net. (2022111412 86400 3600 3600000 300)
|
|||
|
IN NS ns106.ovh.net.
|
|||
|
IN NS dns106.ovh.net.
|
|||
|
IN MX 10 xoyize.xyz.
|
|||
|
IN A 109.123.254.249
|
|||
|
IN AAAA 2a02:c206:2108:3749::1
|
|||
|
IN CAA 128 issue "letsencrypt.org"
|
|||
|
* IN A 109.123.254.249
|
|||
|
* IN AAAA 2a02:c206:2108:3749::1
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="certificats-lets-encrypt">Certificats Let’s Encrypt</h4>
|
|||
|
|
|||
|
<p><img src="/images/letsencrypt-logo-a.png" alt="letsencrypt" height="50" /><br />
|
|||
|
socat est prérequis</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install socat
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installation gestionnaire des certificats Let’s Encrypt</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~
|
|||
|
git clone https://github.com/acmesh-official/acme.sh.git
|
|||
|
cd acme.sh
|
|||
|
./acme.sh --install
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Se reconnecter</p>
|
|||
|
|
|||
|
<p>Exporter les clés OVH API</p>
|
|||
|
|
|||
|
<p>Génération des certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>acme.sh --dns dns_ovh --server letsencrypt --issue --keylength ec-384 -d 'xoyize.xyz' -d '*.xoyize.xyz'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ouvrir le lien d’authentification et relancer la commande précédente après le message “OVH authentication Success !” et patienter…</p>
|
|||
|
|
|||
|
<p>Résultat de l’installation</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Mon 14 Nov 2022 08:18:58 PM CET] Your cert is in: /home/ctbouser//.acme.sh/xoyize.xyz_ecc/xoyize.xyz.cer
|
|||
|
[Mon 14 Nov 2022 08:18:58 PM CET] Your cert key is in: /home/ctbouser//.acme.sh/xoyize.xyz_ecc/xoyize.xyz.key
|
|||
|
[Mon 14 Nov 2022 08:18:58 PM CET] The intermediate CA cert is in: /home/ctbouser//.acme.sh/xoyize.xyz_ecc/ca.cer
|
|||
|
[Mon 14 Nov 2022 08:18:58 PM CET] And the full chain certs is there: /home/ctbouser//.acme.sh/xoyize.xyz_ecc/fullchain.cer
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Installation des certificats</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir -p /etc/ssl/private/
|
|||
|
sudo chown $USER -R /etc/ssl/private/
|
|||
|
acme.sh --ecc --install-cert -d 'xoyize.xyz' -d '*.xoyize.xyz' --key-file /etc/ssl/private/xoyize.xyz-key.pem --fullchain-file /etc/ssl/private/xoyize.xyz-fullchain.pem --reloadcmd 'sudo systemctl reload nginx.service'
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p class="warning">Supprimer <code class="language-plaintext highlighter-rouge">--reloadcmd 'sudo systemctl reload nginx.service'</code> à la ligne précédente si Nginx n’est pas installé</p>
|
|||
|
|
|||
|
<p>Editer le crontab</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>13 0 * * * "/home/ctbouser/.acme.sh"/acme.sh --cron --home "/home/ctbouser/.acme.sh" --renew-hook "/home/ctbouser/.acme.sh/acme.sh --ecc --install-cert -d 'xoyize.xyz' -d '*.xoyize.xyz' --key-file /etc/ssl/private/xoyize.xyz-key.pem --fullchain-file /etc/ssl/private/xoyize.xyz-fullchain.pem --reloadcmd 'sudo systemctl reload nginx.service'" > /dev/null
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="nginx-securityconfinc">Nginx security.conf.inc</h3>
|
|||
|
|
|||
|
<p><img src="/images/nginx-secure-logo.png" alt="letsencrypt" height="50" /><br />
|
|||
|
<a href="/2022/10/22/Nginx_headers_SSL_HSTS_OCSP.html">Nginx headers,SSL,HSTS,OCSP</a></p>
|
|||
|
|
|||
|
<p>Créer un fichier pour un regroupement <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/security.conf.inc</code> mode intermédiaire</p>
|
|||
|
|
|||
|
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1"># /etc/nginx/conf.d/security.conf.inc</span>
|
|||
|
<span class="k">ssl_session_timeout</span> <span class="s">1d</span><span class="p">;</span>
|
|||
|
<span class="k">ssl_session_cache</span> <span class="s">shared:SSL:50m</span><span class="p">;</span> <span class="c1"># about 200000 sessions</span>
|
|||
|
<span class="k">ssl_session_tickets</span> <span class="no">off</span><span class="p">;</span>
|
|||
|
|
|||
|
|
|||
|
<span class="c1"># intermediate configuration</span>
|
|||
|
<span class="k">ssl_protocols</span> <span class="s">TLSv1.2</span> <span class="s">TLSv1.3</span><span class="p">;</span>
|
|||
|
<span class="k">ssl_ciphers</span> <span class="s">ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384</span><span class="p">;</span>
|
|||
|
<span class="k">ssl_prefer_server_ciphers</span> <span class="no">off</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># Pre-defined FFDHE group (RFC 7919)</span>
|
|||
|
<span class="c1"># From https://ssl-config.mozilla.org/ffdhe2048.txt</span>
|
|||
|
<span class="c1"># https://security.stackexchange.com/a/149818</span>
|
|||
|
<span class="k">ssl_dhparam</span> <span class="n">/etc/ssl/private/ffdhe2048.pem</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># Follows the Web Security Directives from the Mozilla Dev Lab and the Mozilla Obervatory + Partners</span>
|
|||
|
<span class="c1"># https://wiki.mozilla.org/Security/Guidelines/Web_Security</span>
|
|||
|
<span class="c1"># https://observatory.mozilla.org/</span>
|
|||
|
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"Content-Security-Policy</span> <span class="p">:</span> <span class="s">upgrade-insecure-requests"</span><span class="p">;</span>
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"Referrer-Policy:</span> <span class="s">same-origin</span><span class="p">;</span><span class="k">"</span>
|
|||
|
|
|||
|
<span class="s">more_set_headers</span> <span class="s">"X-Content-Type-Options</span> <span class="p">:</span> <span class="s">nosniff"</span><span class="p">;</span>
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"X-XSS-Protection</span> <span class="p">:</span> <span class="mi">1</span><span class="p">;</span> <span class="k">mode=block"</span><span class="p">;</span>
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"X-Download-Options</span> <span class="p">:</span> <span class="s">noopen"</span><span class="p">;</span>
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"X-Permitted-Cross-Domain-Policies</span> <span class="p">:</span> <span class="s">none"</span><span class="p">;</span>
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"X-Frame-Options</span> <span class="p">:</span> <span class="s">SAMEORIGIN"</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># Disable the disaster privacy thing that is FLoC</span>
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"Permissions-Policy</span> <span class="p">:</span> <span class="s">interest-cohort=()"</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># Disable gzip to protect against BREACH</span>
|
|||
|
<span class="c1"># Read https://trac.nginx.org/nginx/ticket/1720 (text/html cannot be disabled!)</span>
|
|||
|
<span class="k">gzip</span> <span class="no">off</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># Certificats Let's Encrypt </span>
|
|||
|
<span class="k">ssl_certificate</span> <span class="n">/etc/ssl/private/xoyize.xyz-fullchain.pem</span><span class="p">;</span>
|
|||
|
<span class="k">ssl_certificate_key</span> <span class="n">/etc/ssl/private/xoyize.xyz-key.pem</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># HSTS (ngx_http_headers_module is required) (63072000 seconds)</span>
|
|||
|
<span class="k">more_set_headers</span> <span class="s">"Strict-Transport-Security</span> <span class="p">:</span> <span class="s">max-age=63072000</span><span class="p">;</span> <span class="k">includeSubDomains</span><span class="p">;</span> <span class="k">preload"</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1"># OCSP settings</span>
|
|||
|
<span class="k">ssl_stapling</span> <span class="no">on</span><span class="p">;</span>
|
|||
|
<span class="k">ssl_stapling_verify</span> <span class="no">on</span><span class="p">;</span>
|
|||
|
<span class="k">ssl_trusted_certificate</span> <span class="n">/etc/ssl/private/xoyize.xyz-fullchain.pem</span><span class="p">;</span>
|
|||
|
<span class="k">resolver</span> <span class="mf">1.1</span><span class="s">.1.1</span><span class="p">;</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer le fichier Diffie-Hellmann <code class="language-plaintext highlighter-rouge">/etc/ssl/private/ffdhe2048.pem</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-----BEGIN DH PARAMETERS-----
|
|||
|
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
|||
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
|||
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
|||
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
|||
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
|||
|
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
|||
|
-----END DH PARAMETERS-----
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Dans tous les Vhosts, il faut ajouter l’inclusion du fichier : <code class="language-plaintext highlighter-rouge">include /etc/nginx/conf.d/security.conf.inc;</code></p>
|
|||
|
|
|||
|
<h3 id="fail2ban">Fail2ban</h3>
|
|||
|
|
|||
|
<p><img src="/images/fail2ban.png" alt="" height="50" /> <a href="/2022/09/27/Debian_11_Fail2ban_UFW.html">Installer et configurer Fail2ban + UFW sur Debian 11</a></p>
|
|||
|
|
|||
|
<p>Version installée : <strong>Fail2Ban v0.11.2</strong></p>
|
|||
|
|
|||
|
<h3 id="notifications">Notifications</h3>
|
|||
|
|
|||
|
<p><img src="/images/notification-icon.png" alt="" height="50" /></p>
|
|||
|
|
|||
|
<p><code class="language-plaintext warning highlighter-rouge">Pour certains fournisseurs de VPS, il faut demander l'ouverture du port 25</code></p>
|
|||
|
|
|||
|
<p>Le serveur doit pouvoir expédier des messages de notification par messagerie</p>
|
|||
|
|
|||
|
<ol>
|
|||
|
<li>Il faut ajouter le port TCP 25 au parefeu : <code class="language-plaintext highlighter-rouge">sudo ufw allow 25</code></li>
|
|||
|
<li>Configurer DNS de votre fournisseur de domaine, ici OVH<br />
|
|||
|
Ajouter enregistrement MX : <strong>IN MX 10 xoyize.xyz.</strong> (le point est obligatoire après fr)</li>
|
|||
|
<li>Procédures d’installation et paramétrage →
|
|||
|
<a href="/2022/08/27/Debian_Postfix_serveur_SMTP_envoi_uniquement.html">Debian - Installer et configurer Postfix comme serveur SMTP d’envoi uniquement</a></li>
|
|||
|
</ol>
|
|||
|
|
|||
|
<p>Test envoi message</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "Test envoi via postfix smtp" | mail -s "serveur contabo xoyize.xyz" desti@mail.fr
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="docker-non-actif">Docker (NON ACTIF)</h3>
|
|||
|
|
|||
|
<p><img src="/images/docker-logo.png" alt="" height="50" /><br />
|
|||
|
<a href="/2020/03/10/Docker-Debian-Buster.html">Docker + Docker Compose sur Debian, installation et utilisation</a></p>
|
|||
|
|
|||
|
<ul>
|
|||
|
<li><strong>Docker Engine</strong> ou <strong>Docker Daemon</strong> correspondant au processus qui fait tourner Docker sur le système, en charge de la génération et l’exécution des containers</li>
|
|||
|
<li><strong>Docker Registry</strong> est un emplacement de stockage pour héberger les images de containers Docker (il peut être public ou privé)</li>
|
|||
|
<li><strong>Docker Image</strong> correspondant à un fichier qui contient la définition d’un container Docker (dépendances, configuration, etc.)</li>
|
|||
|
<li><strong>Docker Client</strong> correspondant à l’utilitaire en ligne de commande qui va permettre de gérer les containers (commande “docker”)</li>
|
|||
|
<li><strong>Docker Container</strong> correspondant aux containers en eux-mêmes, tout en sachant qu’une image peut permettre de créer plusieurs containers avec chacun un identifiant unique</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<h2 id="sauvegardes">Sauvegardes</h2>
|
|||
|
|
|||
|
<p><img src="/images/sauvegarde_logo.png" alt="" height="50" /></p>
|
|||
|
|
|||
|
<h3 id="données-srvdatayan">Données /srv/datayan</h3>
|
|||
|
|
|||
|
<p class="info">Le dossier datayan va contenir tous les dossiers de données :<br />
|
|||
|
<strong>BiblioCalibre CalibreTechnique media musique static www</strong><br />
|
|||
|
L’utilisateur doit avoir un ID=1000</p>
|
|||
|
|
|||
|
<p><strong>Opérations sur le serveur HostMyServers contabo (yanfi.space)</strong><br />
|
|||
|
Dans l’installation de base debian 11, l’utilisateur à un ID=1000</p>
|
|||
|
|
|||
|
<p>Ajouter cet utilisateur au groupe users</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo usermod -a -G users $USER
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vérifier : <code class="language-plaintext highlighter-rouge">id $USER</code> → uid=1000(ctbouser) gid=1000(ctbouser) groups=1000(ctbouser),100(users)</p>
|
|||
|
|
|||
|
<p>Créer le dossier</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mkdir -p /srv/datayan
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Donner les droits</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo chown $USER:users -R /srv/datayan
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer un jeu de clés SSH pour se connecter au server32771 (45.145.166.178)</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/hms32771
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ajouter la clé publique <strong>hms32771.pub</strong> au fichier <strong>authorized_keys</strong> du server32771 (45.145.166.178) <br />
|
|||
|
Se connecter avec utilisateur <strong>hmsuser</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -p 55178 -i /home/ctbouser/.ssh/hms32771 hmsuser@45.145.166.178
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Dupliquer le contenu <code class="language-plaintext highlighter-rouge">/srv/datayan/</code> du distant server32771 (45.145.166.178)</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rsync <span class="nt">-avz</span> <span class="nt">--progress</span> <span class="nt">--stats</span> <span class="nt">--human-readable</span> <span class="nt">--delete</span> <span class="se">\</span>
|
|||
|
<span class="nt">--exclude</span><span class="o">={</span><span class="s2">"media"</span><span class="o">}</span> <span class="se">\</span>
|
|||
|
<span class="nt">--rsync-path</span><span class="o">=</span><span class="s2">"sudo rsync"</span> <span class="nt">-e</span> <span class="s2">"ssh -p 55178 -i /home/ctbouser/.ssh/hms32771 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"</span> <span class="se">\</span>
|
|||
|
hmsuser@45.145.166.178:/srv/datayan/<span class="k">*</span> /srv/datayan/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h3 id="borgbackup">BorgBackup</h3>
|
|||
|
|
|||
|
<p><img src="/images/borg-logo-a.png" alt="" height="50" /><br />
|
|||
|
Installer borgbackup :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install borgbackup
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer un utilisateur <strong>borg</strong> et son répertoire “home” → <code class="language-plaintext highlighter-rouge">/srv/data/borg-backups</code> :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo useradd -d /srv/data/borg-backups -m -r -U borg
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Les clés publiques des serveurs autorisés se trouvent dans le fichier <strong>authorized_keys</strong> de l’utilisateur <strong>borg</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>root@ouestyan:/home/ctbouser# su - borg
|
|||
|
$ pwd
|
|||
|
/srv/data/borg-backups
|
|||
|
$ mkdir /srv/data/borg-backups/.ssh
|
|||
|
# Création du fichier des clés autorisées (de chaque serveur ) pour la sauvegarde
|
|||
|
$ nano /srv/data/borg-backups/.ssh/authorized_keys
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ajouter les clés publiques suivantes qui correspondent aux serveurs <strong>ouestline.xyz</strong> et <strong>xoyaz.xyz</strong></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMs2JATwIa9fPOk0gfOgm4YNIT9ZKfWwpXDamzZ5dVsh root@ouestline.xyz
|
|||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPuVXP+pUjvedC/htJmKXamAotLESDCRqU0MOoD7vqCA root@422x.l.time4vps.cloud
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h2 id="xoyizexyz">xoyize.xyz</h2>
|
|||
|
|
|||
|
<h3 id="accueil">Accueil</h3>
|
|||
|
|
|||
|
<p>Déposer une image <code class="language-plaintext highlighter-rouge">wallpaper.jpg</code> dans le dossier <code class="language-plaintext highlighter-rouge">/var/www/default-www</code></p>
|
|||
|
|
|||
|
<p>Créer un fichier <code class="language-plaintext highlighter-rouge">/var/www/default-www/index.html</code></p>
|
|||
|
|
|||
|
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><!DOCTYPE html></span>
|
|||
|
<span class="nt"><html></span>
|
|||
|
<span class="nt"><head></span>
|
|||
|
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"UTF-8"</span><span class="nt">></span>
|
|||
|
<span class="nt"><title></span>xoyize.xyz<span class="nt"></title></span>
|
|||
|
<span class="nt"><style </span><span class="na">type=</span><span class="s">"text/css"</span> <span class="na">media=</span><span class="s">"screen"</span> <span class="nt">></span>
|
|||
|
<span class="nt">html</span> <span class="p">{</span>
|
|||
|
<span class="nl">margin</span><span class="p">:</span><span class="m">0</span><span class="p">;</span>
|
|||
|
<span class="nl">padding</span><span class="p">:</span><span class="m">0</span><span class="p">;</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="sx">url(wallpaper.jpg)</span> <span class="nb">no-repeat</span> <span class="nb">center</span> <span class="nb">fixed</span><span class="p">;</span>
|
|||
|
<span class="nl">-webkit-background-size</span><span class="p">:</span> <span class="n">cover</span><span class="p">;</span> <span class="c">/* pour anciens Chrome et Safari */</span>
|
|||
|
<span class="nl">background-size</span><span class="p">:</span> <span class="n">cover</span><span class="p">;</span> <span class="c">/* version standardisée */</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nt">body</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span> <span class="p">}</span>
|
|||
|
<span class="nt">a</span><span class="nd">:link</span> <span class="p">{</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="n">grey</span><span class="p">;</span>
|
|||
|
<span class="nl">background-color</span><span class="p">:</span> <span class="nb">transparent</span><span class="p">;</span>
|
|||
|
<span class="nl">text-decoration</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="nt">a</span> <span class="p">{</span>
|
|||
|
<span class="nl">text-decoration</span><span class="p">:</span> <span class="nb">underline</span><span class="p">;</span>
|
|||
|
<span class="nl">background-color</span><span class="p">:</span> <span class="nb">transparent</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="m">#a00</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nt">a</span><span class="nd">:visited</span> <span class="p">{</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="m">#844</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="nt">a</span><span class="nd">:hover</span><span class="o">,</span> <span class="nt">a</span><span class="nd">:focus</span><span class="o">,</span> <span class="nt">a</span><span class="nd">:active</span> <span class="p">{</span>
|
|||
|
<span class="nl">text-decoration</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
|
|||
|
<span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
|
|||
|
<span class="nl">background</span><span class="p">:</span> <span class="m">#800</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
|
|||
|
<span class="nt"></style></span>
|
|||
|
|
|||
|
<span class="nt"></head></span>
|
|||
|
<span class="nt"><body></span>
|
|||
|
|
|||
|
<span class="nt"><h1></span>Serveur xoyize.xyz<span class="nt"></h1></span>
|
|||
|
|
|||
|
|
|||
|
<span class="nt"></body></span>
|
|||
|
<span class="nt"></html></span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>xoyize.xyz.conf</strong></p>
|
|||
|
|
|||
|
<p>Créer le fichier <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/xoyize.xyz.conf</code></p>
|
|||
|
|
|||
|
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:80</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">xoyize.xyz</span><span class="p">;</span>
|
|||
|
<span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$host$request_uri</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="c1"># /etc/nginx/conf.d/xoyize.xyz.conf</span>
|
|||
|
|
|||
|
|
|||
|
<span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">xoyize.xyz</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">root</span> <span class="n">/var/www/default-www</span><span class="p">;</span>
|
|||
|
<span class="kn">index</span> <span class="s">index.html</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">include</span> <span class="n">/etc/nginx/conf.d/security.conf.inc</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="c1">#include /etc/nginx/conf.d/xoyize.xyz.d/*.conf;</span>
|
|||
|
|
|||
|
<span class="kn">access_log</span> <span class="n">/var/log/nginx/xoyize.xyz-access.log</span><span class="p">;</span>
|
|||
|
<span class="kn">error_log</span> <span class="n">/var/log/nginx/xoyize.xyz-error.log</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Recharger nginx</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl reload nginx
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Lien <a href="https://xoyize.xyz">https://xoyize.xyz</a> <br />
|
|||
|
<img src="/images/xoyize.xyz.png" alt="" width="500" /></p>
|
|||
|
|
|||
|
<h3 id="navidrome">Navidrome</h3>
|
|||
|
|
|||
|
<p><img src="/images/navidrome-logo.png" alt="" height="50" /><br />
|
|||
|
<a href="/2022/04/02/Audio_Navidrome-installation_sur_debian.html">Audio Navidrome, installation sur debian</a></p>
|
|||
|
|
|||
|
<p><strong><u>Installation navidrome</u></strong></p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Conditions préalables à la mise à jour et à l’installation</span>
|
|||
|
<span class="nb">sudo </span>apt update <span class="o">&&</span> <span class="nb">sudo </span>apt upgrade
|
|||
|
<span class="nb">sudo </span>apt <span class="nb">install </span>libtag1-dev ffmpeg
|
|||
|
<span class="c"># Utilisateur “navidrome”</span>
|
|||
|
<span class="nb">sudo </span>useradd <span class="nt">-r</span> <span class="nt">-s</span> /bin/false navidrome
|
|||
|
<span class="c"># Créez un répertoire pour stocker l’exécutable Navidrome </span>
|
|||
|
<span class="c"># et un répertoire de travail avec les permissions appropriées</span>
|
|||
|
<span class="nb">sudo install</span> <span class="nt">-d</span> <span class="nt">-o</span> navidrome <span class="nt">-g</span> navidrome /opt/navidrome
|
|||
|
<span class="nb">sudo install</span> <span class="nt">-d</span> <span class="nt">-o</span> navidrome <span class="nt">-g</span> navidrome /var/lib/navidrome
|
|||
|
<span class="c"># On utilise la version compilée disponible sous ~/navidrome</span>
|
|||
|
<span class="nb">sudo mv </span>navidrome /opt/navidrome/
|
|||
|
<span class="nb">sudo chown</span> <span class="nt">-R</span> navidrome:navidrome /opt/navidrome
|
|||
|
<span class="nb">sudo chmod</span> +x /opt/navidrome/navidrome
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Fichier de configuration <strong>navidrome.toml</strong> : <code class="language-plaintext highlighter-rouge">sudo nano /var/lib/navidrome/navidrome.toml</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>MusicFolder = "/srv/datayan/musique"
|
|||
|
ND_PLAYLISTSPATH = "/srv/datayan/musique/Playlists"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>unité Systemd <strong>navidrome.service</strong> : <code class="language-plaintext highlighter-rouge">sudo nano /etc/systemd/system/navidrome.service</code></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=navidrome
|
|||
|
Group=navidrome
|
|||
|
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 uncomment the following line if you don't have any media in /home/*.
|
|||
|
# This will prevent navidrome from ever reading/writing anything there.
|
|||
|
#ProtectHome=true
|
|||
|
|
|||
|
# You can customize some Navidrome config options by setting environment variables here. Ex:
|
|||
|
#Environment=ND_BASEURL="/navidrome"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>lancer le service</p>
|
|||
|
|
|||
|
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl daemon-reload
|
|||
|
<span class="nb">sudo </span>systemctl start navidrome.service
|
|||
|
<span class="nb">sudo </span>systemctl <span class="nb">enable </span>navidrome.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Tester navidrome, exécuter la commande sur un poste local ayant accès via ssh au serveur distant</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -L 9500:localhost:4533 ctbouser@109.123.254.249 -p 55249 -i /home/yann/.ssh/contabovps
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ouvrir le lien <code class="language-plaintext highlighter-rouge">localhost:9500</code> dans un navigateur</p>
|
|||
|
|
|||
|
<p><img src="/images/proxy-logo.png" alt="" height="50" /><br />
|
|||
|
<strong><u>Proxy nginx zic.xoyize.xyz</u></strong></p>
|
|||
|
|
|||
|
<p>Le fichier de configuration nginx <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/zic.xoyize.xyz.conf</code></p>
|
|||
|
|
|||
|
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:80</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">zic.xoyize.xyz</span><span class="p">;</span>
|
|||
|
<span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$host$request_uri</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">zic.xoyize.xyz</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">include</span> <span class="n">/etc/nginx/conf.d/security.conf.inc</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
|
|||
|
<span class="kn">proxy_pass</span> <span class="s">http://127.0.0.1:4533</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="p">}</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Valider et recharger ginx</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>Lien <a href="https://zic.xoyize.xyz">https://zic.xoyize.xyz</a><br />
|
|||
|
<img src="/images/zic.xoyize.xyz.png" alt="" width="500" /></p>
|
|||
|
|
|||
|
<h3 id="searx">Searx</h3>
|
|||
|
|
|||
|
<p><a href="https://searx.github.io/searx/admin/installation-searx.html#installation-basic">Step by step installation</a></p>
|
|||
|
|
|||
|
<h4 id="installation-des-paquets-prérequis">Installation des paquets prérequis</h4>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-H</span> apt-get <span class="nb">install</span> <span class="nt">-y</span> <span class="se">\</span>
|
|||
|
python3-dev python3-babel python3-venv <span class="se">\</span>
|
|||
|
uwsgi uwsgi-plugin-python3 <span class="se">\</span>
|
|||
|
git build-essential libxslt-dev zlib1g-dev libffi-dev libssl-dev <span class="se">\</span>
|
|||
|
shellcheck
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Créer un utilisateur système</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-H</span> useradd <span class="nt">--shell</span> /bin/bash <span class="nt">--system</span> <span class="se">\</span>
|
|||
|
<span class="nt">--home-dir</span> <span class="s2">"/usr/local/searx"</span> <span class="se">\</span>
|
|||
|
<span class="nt">--comment</span> <span class="s1">'Privacy-respecting metasearch engine'</span> searx
|
|||
|
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">mkdir</span> <span class="s2">"/usr/local/searx"</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">chown</span> <span class="nt">-R</span> <span class="s2">"searx:searx"</span> <span class="s2">"/usr/local/searx"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="installer-searx-et-les-dépendances">Installer searx et les dépendances</h4>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># basculer sur utilisateur searx</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nt">-u</span> searx <span class="nt">-i</span>
|
|||
|
<span class="c"># le prompt : searx@xoyize:~$</span>
|
|||
|
<span class="c"># cloner le dépôt</span>
|
|||
|
git clone <span class="s2">"https://github.com/searx/searx.git"</span> <span class="s2">"/usr/local/searx/searx-src"</span>
|
|||
|
<span class="c"># créer virtualenv</span>
|
|||
|
python3 <span class="nt">-m</span> venv <span class="s2">"/usr/local/searx/searx-pyenv"</span>
|
|||
|
<span class="nb">echo</span> <span class="s2">". /usr/local/searx/searx-pyenv/bin/activate"</span> <span class="o">>></span> <span class="s2">"/usr/local/searx/.profile"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour installer les dépendances de searx, quittez la session bash searx que vous avez ouverte ci-dessus et redémarrez-en une nouvelle.
|
|||
|
Avant l’installation, vérifiez d’abord si votre virtualenv provient du login (<code class="language-plaintext highlighter-rouge">~/.profile</code>) :</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ctbouser@xoyize:~<span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-H</span> <span class="nt">-u</span> searx <span class="nt">-i</span>
|
|||
|
<span class="o">(</span>searx-pyenv<span class="o">)</span> searx@xoyize:~<span class="nv">$ </span><span class="nb">command</span> <span class="nt">-v</span> python <span class="o">&&</span> python <span class="nt">--version</span>
|
|||
|
/usr/local/searx/searx-pyenv/bin/python
|
|||
|
Python 3.9.2
|
|||
|
|
|||
|
<span class="c"># update pip's boilerplate ..</span>
|
|||
|
pip <span class="nb">install</span> <span class="nt">-U</span> pip
|
|||
|
pip <span class="nb">install</span> <span class="nt">-U</span> setuptools
|
|||
|
pip <span class="nb">install</span> <span class="nt">-U</span> wheel
|
|||
|
pip <span class="nb">install</span> <span class="nt">-U</span> pyyaml
|
|||
|
|
|||
|
<span class="c"># jump to searx's working tree and install searx into virtualenv</span>
|
|||
|
<span class="o">(</span>searx-pyenv<span class="o">)</span> searx@xoyize:~<span class="nv">$ </span><span class="nb">cd</span> <span class="s2">"/usr/local/searx/searx-src"</span>
|
|||
|
<span class="c"># Ne pas oublier le "poin" à la fin de la commande</span>
|
|||
|
<span class="o">(</span>searx-pyenv<span class="o">)</span> searx@xoyize:~<span class="nv">$ </span>pip <span class="nb">install</span> <span class="nt">-e</span> <span class="nb">.</span>
|
|||
|
<span class="c"># on sort</span>
|
|||
|
<span class="nb">exit</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="configuration">Configuration</h4>
|
|||
|
|
|||
|
<p>Pour créer un /etc/searx/settings.yml initial, vous pouvez commencer par une copie du fichier <code class="language-plaintext highlighter-rouge">Origin : utils/templates/etc/searx/use_default_settings.yml</code>. Cette configuration utilise les paramètres par défaut de <code class="language-plaintext highlighter-rouge">Origin : searx/settings.yml</code> et est recommandée depuis la fusion du PR 2291.</p>
|
|||
|
|
|||
|
<p>Pour une installation minimale, configurez comme indiqué ci-dessous - remplacez searx@$(uname -n) par un nom de votre choix, définissez ultrasecretkey - et/ou modifiez /etc/searx/settings.yml selon vos besoins.</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># paramètres searx</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"/etc/searx"</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">cp</span> <span class="s2">"/usr/local/searx/searx-src/searx/settings.yml"</span> <span class="se">\</span>
|
|||
|
<span class="s2">"/etc/searx/settings.yml"</span>
|
|||
|
<span class="c"># minimal setup</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="nt">-e</span> <span class="s2">"s/ultrasecretkey/</span><span class="si">$(</span>openssl rand <span class="nt">-hex</span> 16<span class="si">)</span><span class="s2">/g"</span> <span class="s2">"/etc/searx/settings.yml"</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="nt">-e</span> <span class="s2">"s/{instance_name}/searx@</span><span class="si">$(</span><span class="nb">uname</span> <span class="nt">-n</span><span class="si">)</span><span class="s2">/g"</span> <span class="s2">"/etc/searx/settings.yml"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier le fichier de paramétrage <code class="language-plaintext highlighter-rouge">/etc/searx/settings.yml</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>general:
|
|||
|
|
|||
|
instance_name : "XoSearx" # displayed name
|
|||
|
|
|||
|
ui:
|
|||
|
theme_args :
|
|||
|
oscar_style : logicodev-dark # default style of oscar
|
|||
|
results_on_new_tab: True # Open result links in a new tab by default
|
|||
|
|
|||
|
# supprimer la ligne 'disabled : True' des éléments ci dessous ou positionner 'disabled : False'
|
|||
|
|
|||
|
- name : ddg definitions
|
|||
|
engine : duckduckgo_definitions
|
|||
|
shortcut : ddd
|
|||
|
weight : 2
|
|||
|
|
|||
|
- name : duckduckgo
|
|||
|
engine : duckduckgo
|
|||
|
shortcut : ddg
|
|||
|
|
|||
|
- name : duckduckgo images
|
|||
|
engine : duckduckgo_images
|
|||
|
shortcut : ddi
|
|||
|
timeout: 3.0
|
|||
|
|
|||
|
- name : startpage
|
|||
|
engine : startpage
|
|||
|
shortcut : sp
|
|||
|
timeout : 6.0
|
|||
|
disabled : False
|
|||
|
additional_tests:
|
|||
|
rosebud: *test_rosebud
|
|||
|
|
|||
|
# facultatif
|
|||
|
# ajouter ligne 'disabled : True' sur certains éléments de la liste
|
|||
|
|
|||
|
- name : bing
|
|||
|
engine : bing
|
|||
|
shortcut : bi
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : bing images
|
|||
|
engine : bing_images
|
|||
|
shortcut : bii
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : bing news
|
|||
|
engine : bing_news
|
|||
|
shortcut : bin
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : bing videos
|
|||
|
engine : bing_videos
|
|||
|
shortcut : biv
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : wikidata
|
|||
|
engine : wikidata
|
|||
|
shortcut : wd
|
|||
|
timeout : 3.0
|
|||
|
weight : 2
|
|||
|
tests: *tests_infobox
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : google
|
|||
|
engine : google
|
|||
|
shortcut : go
|
|||
|
use_mobile_ui: false
|
|||
|
# additional_tests:
|
|||
|
# android: *test_android
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : google images
|
|||
|
engine : google_images
|
|||
|
shortcut : goi
|
|||
|
# additional_tests:
|
|||
|
# android: *test_android
|
|||
|
# dali:
|
|||
|
# matrix:
|
|||
|
# query: ['Dali Christ']
|
|||
|
# lang: ['en', 'de', 'fr', 'zh-CN']
|
|||
|
# result_container:
|
|||
|
# - ['one_title_contains', 'Salvador']
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : google news
|
|||
|
engine : google_news
|
|||
|
shortcut : gon
|
|||
|
# additional_tests:
|
|||
|
# android: *test_android
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : google videos
|
|||
|
engine : google_videos
|
|||
|
shortcut : gov
|
|||
|
# additional_tests:
|
|||
|
# android: *test_android
|
|||
|
disabled : True
|
|||
|
|
|||
|
- name : google scholar
|
|||
|
engine : google_scholar
|
|||
|
shortcut : gos
|
|||
|
disabled : True
|
|||
|
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="vérifier-en-local">Vérifier en local</h4>
|
|||
|
|
|||
|
<p>Pour vérifier votre configuration searx, vous pouvez activer le débogage et démarrer la webapp. Searx recherche un fichier de configuration dans l’environnement exporté <code class="language-plaintext highlighter-rouge">$SEARX_SETTINGS_PATH</code></p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># dans le terminal (ctbouser@ouestyan:~$)</span>
|
|||
|
<span class="c"># enable debug ..</span>
|
|||
|
<span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="nt">-e</span> <span class="s2">"s/debug : False/debug : True/g"</span> <span class="s2">"/etc/searx/settings.yml"</span>
|
|||
|
|
|||
|
<span class="c"># start webapp</span>
|
|||
|
<span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-H</span> <span class="nt">-u</span> searx <span class="nt">-i</span>
|
|||
|
<span class="c"># prompt --> (searx-pyenv) searx@xoyize:~$ </span>
|
|||
|
<span class="nb">cd</span> /usr/local/searx/searx-src
|
|||
|
<span class="nb">export </span><span class="nv">SEARX_SETTINGS_PATH</span><span class="o">=</span><span class="s2">"/etc/searx/settings.yml"</span>
|
|||
|
<span class="c"># lancement de la webapp</span>
|
|||
|
python searx/webapp.py
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le serveur de test est en attente<br />
|
|||
|
<img src="/images/xoyize001.png" alt="" /></p>
|
|||
|
|
|||
|
<p><strong>Alternative A</strong><br />
|
|||
|
Ouvrez un navigateur WEB et visitez http:// . Si vous êtes dans un conteneur ou dans un script, testez avec curl dans le second terminal</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl --location --verbose --head --insecure localhost:8888
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>* Trying 127.0.0.1:8888...
|
|||
|
* Connected to localhost (127.0.0.1) port 8888 (#0)
|
|||
|
> GET / HTTP/1.1
|
|||
|
> Host: localhost:8888
|
|||
|
> User-Agent: curl/7.74.0
|
|||
|
> Accept: */*
|
|||
|
>
|
|||
|
* Mark bundle as not supporting multiuse
|
|||
|
* HTTP 1.0, assume close after body
|
|||
|
< HTTP/1.0 200 OK
|
|||
|
[...]
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><strong>Alternative B</strong><br />
|
|||
|
Dans un terminal distant ayant un accès SSH au serveur xoyize.xyz</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -L 9500:localhost:8888 ctbouser@109.123.254.249 -p 55249 -i /home/yann/.ssh/contabovps
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Puis ouvrir un navigateur sur le lien <a href="http://localhost:9500">http://localhost:9500</a></p>
|
|||
|
|
|||
|
<p><strong>Constat</strong><br />
|
|||
|
Si tout fonctionne bien, appuyez sur [CTRL-C] pour arrêter la webapp et désactiver l’option de débogage dans settings.yml.</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># disable debug</span>
|
|||
|
<span class="nv">$ </span><span class="nb">sudo</span> <span class="nt">-H</span> <span class="nb">sed</span> <span class="nt">-i</span> <span class="nt">-e</span> <span class="s2">"s/debug : True/debug : False/g"</span> <span class="s2">"/etc/searx/settings.yml"</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Vous pouvez maintenant quitter searx en mode bash (commande exit). À ce stade, searx n’est pas un daemon , uwsgi le permet.</p>
|
|||
|
|
|||
|
<h4 id="uwsgi">uwsgi</h4>
|
|||
|
|
|||
|
<p>Créer le fichier <code class="language-plaintext highlighter-rouge">/etc/uwsgi/apps-available/searx.ini</code></p>
|
|||
|
|
|||
|
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[uwsgi]</span>
|
|||
|
|
|||
|
<span class="c"># uWSGI core
|
|||
|
# ----------
|
|||
|
#
|
|||
|
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
|||
|
</span>
|
|||
|
<span class="c"># Who will run the code
|
|||
|
</span><span class="py">uid</span> <span class="p">=</span> <span class="s">searx</span>
|
|||
|
<span class="py">gid</span> <span class="p">=</span> <span class="s">searx</span>
|
|||
|
|
|||
|
<span class="c"># set (python) default encoding UTF-8
|
|||
|
</span><span class="py">env</span> <span class="p">=</span> <span class="s">LANG=C.UTF-8</span>
|
|||
|
<span class="py">env</span> <span class="p">=</span> <span class="s">LANGUAGE=C.UTF-8</span>
|
|||
|
<span class="py">env</span> <span class="p">=</span> <span class="s">LC_ALL=C.UTF-8</span>
|
|||
|
|
|||
|
<span class="c"># chdir to specified directory before apps loading
|
|||
|
</span><span class="py">chdir</span> <span class="p">=</span> <span class="s">/usr/local/searx/searx-src/searx</span>
|
|||
|
|
|||
|
<span class="c"># searx configuration (settings.yml)
|
|||
|
</span><span class="py">env</span> <span class="p">=</span> <span class="s">SEARX_SETTINGS_PATH=/etc/searx/settings.yml</span>
|
|||
|
|
|||
|
<span class="c"># disable logging for privacy
|
|||
|
</span><span class="py">disable-logging</span> <span class="p">=</span> <span class="s">true</span>
|
|||
|
|
|||
|
<span class="c"># The right granted on the created socket
|
|||
|
</span><span class="py">chmod-socket</span> <span class="p">=</span> <span class="s">666</span>
|
|||
|
|
|||
|
<span class="c"># Plugin to use and interpreter config
|
|||
|
</span><span class="py">single-interpreter</span> <span class="p">=</span> <span class="s">true</span>
|
|||
|
|
|||
|
<span class="c"># enable master process
|
|||
|
</span><span class="py">master</span> <span class="p">=</span> <span class="s">true</span>
|
|||
|
|
|||
|
<span class="c"># load apps in each worker instead of the master
|
|||
|
</span><span class="py">lazy-apps</span> <span class="p">=</span> <span class="s">true</span>
|
|||
|
|
|||
|
<span class="c"># load uWSGI plugins
|
|||
|
</span><span class="py">plugin</span> <span class="p">=</span> <span class="s">python3,http</span>
|
|||
|
|
|||
|
<span class="c"># By default the Python plugin does not initialize the GIL. This means your
|
|||
|
# app-generated threads will not run. If you need threads, remember to enable
|
|||
|
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
|||
|
# threads options) will automatically enable threading support. This *strange*
|
|||
|
# default behaviour is for performance reasons.
|
|||
|
</span><span class="py">enable-threads</span> <span class="p">=</span> <span class="s">true</span>
|
|||
|
|
|||
|
|
|||
|
<span class="c"># plugin: python
|
|||
|
# --------------
|
|||
|
#
|
|||
|
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
|||
|
</span>
|
|||
|
<span class="c"># load a WSGI module
|
|||
|
</span><span class="py">module</span> <span class="p">=</span> <span class="s">searx.webapp</span>
|
|||
|
|
|||
|
<span class="c"># set PYTHONHOME/virtualenv
|
|||
|
</span><span class="py">virtualenv</span> <span class="p">=</span> <span class="s">/usr/local/searx/searx-pyenv</span>
|
|||
|
|
|||
|
<span class="c"># add directory (or glob) to pythonpath
|
|||
|
</span><span class="py">pythonpath</span> <span class="p">=</span> <span class="s">/usr/local/searx/searx-src</span>
|
|||
|
|
|||
|
|
|||
|
<span class="c"># speak to upstream
|
|||
|
# -----------------
|
|||
|
#
|
|||
|
# Activate the 'http' configuration for filtron or activate the 'socket'
|
|||
|
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
|||
|
</span>
|
|||
|
<span class="c"># using IP:
|
|||
|
#
|
|||
|
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
|||
|
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
|||
|
</span>
|
|||
|
<span class="py">http</span> <span class="p">=</span> <span class="s">127.0.0.1:8888</span>
|
|||
|
|
|||
|
<span class="c"># using unix-sockets:
|
|||
|
#
|
|||
|
# On some distributions you need to create the app folder for the sockets::
|
|||
|
#
|
|||
|
# mkdir -p /run/uwsgi/app/searx
|
|||
|
# chown -R searx:searx /run/uwsgi/app/searx
|
|||
|
#
|
|||
|
# socket = /run/uwsgi/app/searx/socket
|
|||
|
</span>
|
|||
|
<span class="c"># Cache
|
|||
|
</span><span class="py">cache2</span> <span class="p">=</span> <span class="s">name=searxcache,items=2000,blocks=2000,blocksize=4096,bitmap=1</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Sur certaines distributions, vous devez créer le dossier app pour les sockets</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mkdir</span> <span class="nt">-p</span> /run/uwsgi/app/searx
|
|||
|
<span class="nb">sudo chown</span> <span class="nt">-R</span> searx:searx /run/uwsgi/app/searx
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>socket = /run/uwsgi/app/searx/socket</p>
|
|||
|
|
|||
|
<p>Activer le fichier ini</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -H ln -s /etc/uwsgi/apps-available/searx.ini /etc/uwsgi/apps-enabled/
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Démarrer le service</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-H</span> service uwsgi start searx
|
|||
|
<span class="c"># OU</span>
|
|||
|
<span class="nb">sudo </span>systemctl start uwsgi
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Tester localement pour vérifier : <code class="language-plaintext highlighter-rouge">curl --location --verbose --head --insecure localhost:8888</code></p>
|
|||
|
|
|||
|
<p>Tester à partir d’un poste distant<br />
|
|||
|
Exécuter sur un poste distant</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh -L 9500:localhost:8888 ctbouser@109.123.254.249 -p 55249 -i /home/yann/.ssh/contabovps
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Sur le même poste , ouvrir le navigateur avec un lien <a href="http://localhost:9500">http://localhost:9500</a><br />
|
|||
|
<img src="/images/searx.xoyize.xyz.png" alt="" width="600" /></p>
|
|||
|
|
|||
|
<p class="info">Après toute modification du fichier de configuration <code class="language-plaintext highlighter-rouge">/etc/searx/settings.yml</code>, il faut redémarrer le service <strong>uwsgi</strong> par la commande <code class="language-plaintext highlighter-rouge">sudo systemctl restart uwsgi</code></p>
|
|||
|
|
|||
|
<h4 id="nginx-proxy-searx">nginx proxy searx</h4>
|
|||
|
|
|||
|
<p><img src="/images/proxy-logo.png" alt="" height="50" /><br />
|
|||
|
Le fichier de configuration nginx <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/searx.xoyize.xyz.conf</code></p>
|
|||
|
|
|||
|
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:80</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">searx.xoyize.xyz</span><span class="p">;</span>
|
|||
|
<span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$host$request_uri</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">searx.xoyize.xyz</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">include</span> <span class="n">/etc/nginx/conf.d/security.conf.inc</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
|
|||
|
<span class="kn">proxy_pass</span> <span class="s">http://127.0.0.1:8888</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_set_header</span> <span class="s">Connection</span> <span class="nv">$http_connection</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">X-Scheme</span> <span class="nv">$scheme</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_buffering</span> <span class="no">off</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="p">}</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Valider et recharger ginx</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>Lien <a href="https://searx.xoyize.xyz">https://searx.xoyize.xyz</a><br />
|
|||
|
<img src="/images/searx.xoyize.xyz-a.png" alt="" width="600" /></p>
|
|||
|
|
|||
|
<h3 id="nextcloud">Nextcloud</h3>
|
|||
|
|
|||
|
<p><a href="/2022/10/19/Nextcloud_Hub_3_(v25+).html">Nextcloud Hub 3 (v25+)</a></p>
|
|||
|
|
|||
|
<h4 id="transmission-torrent">Transmission Torrent</h4>
|
|||
|
|
|||
|
<p><img src="/images/transmission-logo.png" alt="" /><br />
|
|||
|
<a href="/2020/11/07/debian-transmission-daemon.html">Installation Transmission Torrent</a></p>
|
|||
|
|
|||
|
<h4 id="installer-transmission-daemon">Installer transmission-daemon</h4>
|
|||
|
|
|||
|
<p>Liste des commandes</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>transmission-cli transmission-common transmission-daemon
|
|||
|
<span class="nb">sudo </span>systemctl stop transmission-daemon
|
|||
|
<span class="nb">sudo </span>usermod <span class="nt">-a</span> <span class="nt">-G</span> debian-transmission <span class="nv">$USER</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>On arrête le daemon pour pouvoir modifier le fichier de configuration :</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop transmission-daemon.service
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="proxy-nginx">Proxy nginx</h4>
|
|||
|
|
|||
|
<p><img src="/images/proxy-logo.png" alt="" height="50" /><br />
|
|||
|
Reverse proxy nginx <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/transmission.xoyize.xyz.conf</code></p>
|
|||
|
|
|||
|
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">upstream</span> <span class="s">transmission</span> <span class="p">{</span>
|
|||
|
<span class="kn">server</span> <span class="nf">127.0.0.1</span><span class="p">:</span><span class="mi">9091</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:80</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">transmission.xoyize.xyz</span><span class="p">;</span>
|
|||
|
<span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$host$request_uri</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="k">server</span> <span class="p">{</span>
|
|||
|
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
|
|||
|
<span class="kn">server_name</span> <span class="s">transmission.xoyize.xyz</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">include</span> <span class="n">/etc/nginx/conf.d/security.conf.inc</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">access_log</span> <span class="n">/var/log/nginx/trans-access.log</span><span class="p">;</span>
|
|||
|
<span class="kn">error_log</span> <span class="n">/var/log/nginx/trans-error.log</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
|
|||
|
<span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$server_name</span><span class="n">/transmission/</span><span class="p">;</span>
|
|||
|
<span class="kn">location</span> <span class="s">^~</span> <span class="n">/transmission</span> <span class="p">{</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">X-Real-IP</span> <span class="nv">$remote_addr</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$http_host</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_set_header</span> <span class="s">Connection</span> <span class="s">""</span><span class="p">;</span>
|
|||
|
<span class="kn">proxy_pass_header</span> <span class="s">X-Transmission-Session-Id</span><span class="p">;</span>
|
|||
|
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/rpc</span> <span class="p">{</span>
|
|||
|
<span class="kn">proxy_pass</span> <span class="s">http://transmission</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/web/</span> <span class="p">{</span>
|
|||
|
<span class="kn">proxy_pass</span> <span class="s">http://transmission</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/upload</span> <span class="p">{</span>
|
|||
|
<span class="kn">proxy_pass</span> <span class="s">http://transmission</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/web/style/</span> <span class="p">{</span>
|
|||
|
<span class="kn">alias</span> <span class="n">/usr/share/transmission/web/style/</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/web/javascript/</span> <span class="p">{</span>
|
|||
|
<span class="kn">alias</span> <span class="n">/usr/share/transmission/web/javascript/</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/web/images/</span> <span class="p">{</span>
|
|||
|
<span class="kn">alias</span> <span class="n">/usr/share/transmission/web/images/</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/</span> <span class="p">{</span>
|
|||
|
<span class="kn">return</span> <span class="mi">301</span> <span class="s">http://</span><span class="nv">$server_name</span><span class="n">/transmission/web</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="kn">location</span> <span class="n">/transmission/downloads/</span> <span class="p">{</span>
|
|||
|
<span class="kn">alias</span> <span class="n">/srv/transmission/completed/</span><span class="p">;</span>
|
|||
|
<span class="kn">charset</span> <span class="s">UTF-8</span><span class="p">;</span>
|
|||
|
<span class="kn">autoindex</span> <span class="no">on</span><span class="p">;</span>
|
|||
|
<span class="kn">autoindex_exact_size</span> <span class="no">off</span><span class="p">;</span>
|
|||
|
<span class="p">}</span>
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="p">}</span>
|
|||
|
|
|||
|
<span class="p">}</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="dossiers-et-configuration">Dossiers et configuration</h4>
|
|||
|
|
|||
|
<p><img src="/images/dossier-logo.png" alt="" height="50" /><br />
|
|||
|
Créer les différents dossiers pour le suivi des téléchargements</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mkdir</span> <span class="nt">-p</span> /srv/transmission/<span class="o">{</span>watched,completed,progress<span class="o">}</span>
|
|||
|
<span class="c"># les droits</span>
|
|||
|
<span class="nb">sudo chown </span>debian-transmission:www-data <span class="nt">-R</span> /srv/transmission/completed
|
|||
|
<span class="nb">sudo chown </span>debian-transmission:debian-transmission <span class="nt">-R</span> /srv/transmission/<span class="o">{</span>watched,progress<span class="o">}</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Modifier le fichier <code class="language-plaintext highlighter-rouge">/var/lib/transmission-daemon/info/settings.json</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"download-dir": "/srv/transmission/completed",
|
|||
|
"incomplete-dir": "/srv/transmission/progress",
|
|||
|
|
|||
|
"rpc-authentication-required": true, // Activation de l’auth par mot de passe
|
|||
|
"rpc-url": "/",
|
|||
|
"rpc-bind-address": "0.0.0.0", // 127.0.0.1 pour écouter en local
|
|||
|
"rpc-enabled": true, // Activation de l’interface web
|
|||
|
"rpc-password": "MOT_DE_PASSE", // Tapez votre mot de passe, il sera salé au reload
|
|||
|
"rpc-port": 9091, // Port d’écoute
|
|||
|
"rpc-url": "/transmission/", // Correspond à l’URL d’accès
|
|||
|
"rpc-username": "UTILISATEUR", // Nom d’utilisateur pour l’auth
|
|||
|
"rpc-host-whitelist": "",
|
|||
|
"rpc-host-whitelist-enabled": false,
|
|||
|
"rpc-whitelist": "127.0.0.1", // IPs à whitelist
|
|||
|
"rpc-whitelist-enabled": true, // Activation de la whitelist
|
|||
|
|
|||
|
# en fin de fichier
|
|||
|
"utp-enabled": true,
|
|||
|
"watch-dir": "/srv/transmission/watched",
|
|||
|
"watch-dir-enabled": true
|
|||
|
}
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Si on veut un accès par log et mot de passe, il faut modifier 3 paramètres</p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> "rpc-authentication-required": true,
|
|||
|
"rpc-password": "Mot de passe utilisateur",
|
|||
|
"rpc-username": "yako",
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Le mot de passe sera chiffrée au premier lancement du service</p>
|
|||
|
|
|||
|
<p>le fichier json complet</p>
|
|||
|
|
|||
|
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
|
|||
|
</span><span class="nl">"alt-speed-down"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"alt-speed-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"alt-speed-time-begin"</span><span class="p">:</span><span class="w"> </span><span class="mi">540</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"alt-speed-time-day"</span><span class="p">:</span><span class="w"> </span><span class="mi">127</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"alt-speed-time-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"alt-speed-time-end"</span><span class="p">:</span><span class="w"> </span><span class="mi">1020</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"alt-speed-up"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"bind-address-ipv4"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.0.0.0"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"bind-address-ipv6"</span><span class="p">:</span><span class="w"> </span><span class="s2">"::"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"blocklist-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"blocklist-url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://www.example.com/blocklist"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"cache-size-mb"</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"dht-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"download-dir"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/srv/transmission/completed"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"download-queue-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"download-queue-size"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"encryption"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"idle-seeding-limit"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"idle-seeding-limit-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"incomplete-dir"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/srv/transmission/progress"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"incomplete-dir-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"lpd-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"max-peers-global"</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"message-level"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-congestion-algorithm"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-id-ttl-hours"</span><span class="p">:</span><span class="w"> </span><span class="mi">6</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-limit-global"</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-limit-per-torrent"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-port"</span><span class="p">:</span><span class="w"> </span><span class="mi">51413</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-port-random-high"</span><span class="p">:</span><span class="w"> </span><span class="mi">65535</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-port-random-low"</span><span class="p">:</span><span class="w"> </span><span class="mi">49152</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-port-random-on-start"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"peer-socket-tos"</span><span class="p">:</span><span class="w"> </span><span class="s2">"default"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"pex-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"port-forwarding-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"preallocation"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"prefetch-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"queue-stalled-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"queue-stalled-minutes"</span><span class="p">:</span><span class="w"> </span><span class="mi">30</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"ratio-limit"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"ratio-limit-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rename-partial-files"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-authentication-required"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-bind-address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"127.0.0.1"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-host-whitelist"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-host-whitelist-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-password"</span><span class="p">:</span><span class="w"> </span><span class="s2">"{37ed0549b52529120e94899628667f64d32f7908fhfjT0.Q"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-port"</span><span class="p">:</span><span class="w"> </span><span class="mi">9091</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-url"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/transmission/"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-username"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yako"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-whitelist"</span><span class="p">:</span><span class="w"> </span><span class="s2">"127.0.0.1,::1"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"rpc-whitelist-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"scrape-paused-torrents-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"script-torrent-done-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"script-torrent-done-filename"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"seed-queue-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"seed-queue-size"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"speed-limit-down"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"speed-limit-down-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"speed-limit-up"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"speed-limit-up-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"start-added-torrents"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"trash-original-torrent-files"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"umask"</span><span class="p">:</span><span class="w"> </span><span class="mi">18</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"upload-slots-per-torrent"</span><span class="p">:</span><span class="w"> </span><span class="mi">14</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"utp-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"watch-dir"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/srv/transmission/watched"</span><span class="p">,</span><span class="w">
|
|||
|
</span><span class="nl">"watch-dir-enabled"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
|
|||
|
</span><span class="p">}</span><span class="w">
|
|||
|
</span></code></pre></div></div>
|
|||
|
|
|||
|
<p>Pour éviter l’erreur “ transmission UDP Failed to set receive buffer …” , en mode su</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">echo</span> <span class="s2">"net.core.rmem_max = 4194304"</span> <span class="o">>></span> /etc/sysctl.conf
|
|||
|
<span class="nb">echo</span> <span class="s2">"net.core.wmem_max = 1048576"</span> <span class="o">>></span> /etc/sysctl.conf
|
|||
|
sysctl <span class="nt">-p</span>
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Redémarrer les services</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl start transmission-daemon
|
|||
|
<span class="nb">sudo </span>systemctl reload nginx
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>A chaque modification (en mode su)</p>
|
|||
|
|
|||
|
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl stop transmission-daemon
|
|||
|
<span class="nb">rm</span> /var/lib/transmission-daemon/.config/transmission-daemon/settings.json
|
|||
|
<span class="nb">rm</span> /etc/transmission-daemon/settings.json
|
|||
|
<span class="c"># créer</span>
|
|||
|
nano /var/lib/transmission-daemon/info/settings.json
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<h4 id="transmissionxoyizexyz">transmission.xoyize.xyz</h4>
|
|||
|
|
|||
|
<p>Connexion sur le lien <a href="https://transmission.xoyize.xyz">https://transmission.xoyize.xyz</a><br />
|
|||
|
<img src="/images/transmission.xoyize.xyz.png" alt="" /><br />
|
|||
|
Saisir “yannick” et son mot de passe</p>
|
|||
|
|
|||
|
<h3 id="test-de-sécurité">Test de sécurité</h3>
|
|||
|
|
|||
|
<p><img src="/images/securite-logo.png" alt="" height="50" /><br />
|
|||
|
<a href="https://www.ssllabs.com/ssltest/index.html">Analyse SSL</a> contre le site Web pour trouver le score et la vulnérabilité essentielle.<br />
|
|||
|
<img src="/images/ssllabs-xoyize.xyz.png" alt="" /><br />
|
|||
|
<a href="https://www.ssllabs.com/ssltest/analyze.html?d=xoyize.xyz">https://www.ssllabs.com/ssltest/analyze.html?d=xoyize.xyz</a></p>
|
|||
|
|
|||
|
<p>Les entêtes <a href="https://securityheaders.com/">https://securityheaders.com/</a> <br />
|
|||
|
<img src="/images/securityheaders-xoyize.png" alt="" /><br />
|
|||
|
xoyize.xyz</p>
|
|||
|
|
|||
|
<h2 id="annexe">Annexe</h2>
|
|||
|
|
|||
|
<h3 id="ssh-et-ping-erreur-en-ipv4">ssh et ping erreur en IPV4</h3>
|
|||
|
|
|||
|
<p>Impossible de se connecter en IPV4 par SSH et ping erreur depuis un poste distant<br />
|
|||
|
<img src="/images/xoyize004.png" alt="" /></p>
|
|||
|
|
|||
|
<p>L’exécution du ping par un utilisateur non root provoque une erreur “socket” en interne<br />
|
|||
|
<img src="/images/xoyize002.png" alt="" /><br />
|
|||
|
<em>Sur une installation standard, la plupart des systèmes ne rencontrent pas ce problème.</em></p>
|
|||
|
|
|||
|
<p>Résolution<br />
|
|||
|
Ajout du paramètre : <code class="language-plaintext highlighter-rouge">net.ipv4.ping_group_range</code> dans le fichier <code class="language-plaintext highlighter-rouge">/etc/sysctl.conf</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>net.ipv4.ping_group_range="0 2147483647"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p>Ce paramètre permettra aux utilisateurs non-roots d’exécuter ping
|
|||
|
Le définir temporairement à la volée avec la commande <code class="language-plaintext highlighter-rouge">sysctl</code></p>
|
|||
|
|
|||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sysctl net.ipv4.ping_group_range="0 2147483647"
|
|||
|
</code></pre></div></div>
|
|||
|
|
|||
|
<p><img src="/images/xoyize003.png" alt="" /></p>
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2022-11-15T00: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="/2022/11/09/Installation-Ruby-via-rbenv+Jekyll-sur-Debian.html">Installation Ruby (via rbenv) + Jekyll (générateur de site statique) sur Debian</a></div><div class="next"><span>SUIVANT</span><a href="/2022/11/21/Boite_de_stockage_BX11_Hetzner_Online_Storage_Box.html">Boîtes de stockage BX11 Hetzner Online Storage Box</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>
|
|||
|
|